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

Side by Side Diff: test/cctest/asmjs/test-typing-asm.cc

Issue 2146853004: [wasm] Drop old typing-asm and its tests. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 5 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 | « test/cctest/OWNERS ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "src/v8.h"
6
7 #include "src/asmjs/typing-asm.h"
8 #include "src/ast/ast-expression-visitor.h"
9 #include "src/ast/ast.h"
10 #include "src/ast/scopes.h"
11 #include "src/parsing/parser.h"
12 #include "src/parsing/rewriter.h"
13 #include "src/type-cache.h"
14 #include "test/cctest/cctest.h"
15 #include "test/cctest/expression-type-collector-macros.h"
16 #include "test/cctest/expression-type-collector.h"
17
18 // Macros for function types.
19 #define FUNC_FOREIGN_TYPE Bounds(Type::Function(Type::Any(), zone))
20 #define FUNC_V_TYPE Bounds(Type::Function(Type::Undefined(), zone))
21 #define FUNC_I_TYPE Bounds(Type::Function(cache.kAsmSigned, zone))
22 #define FUNC_F_TYPE Bounds(Type::Function(cache.kAsmFloat, zone))
23 #define FUNC_D_TYPE Bounds(Type::Function(cache.kAsmDouble, zone))
24 #define FUNC_D2D_TYPE \
25 Bounds(Type::Function(cache.kAsmDouble, cache.kAsmDouble, zone))
26 #define FUNC_N2F_TYPE \
27 Bounds(Type::Function(cache.kAsmFloat, Type::Number(), zone))
28 #define FUNC_I2I_TYPE \
29 Bounds(Type::Function(cache.kAsmSigned, cache.kAsmInt, zone))
30 #define FUNC_II2D_TYPE \
31 Bounds(Type::Function(cache.kAsmDouble, cache.kAsmInt, cache.kAsmInt, zone))
32 #define FUNC_II2I_TYPE \
33 Bounds(Type::Function(cache.kAsmSigned, cache.kAsmInt, cache.kAsmInt, zone))
34 #define FUNC_DD2D_TYPE \
35 Bounds(Type::Function(cache.kAsmDouble, cache.kAsmDouble, cache.kAsmDouble, \
36 zone))
37 #define FUNC_NN2N_TYPE \
38 Bounds(Type::Function(Type::Number(), Type::Number(), Type::Number(), zone))
39 #define FUNC_N2N_TYPE \
40 Bounds(Type::Function(Type::Number(), Type::Number(), zone))
41
42 // Macros for array types.
43 #define FLOAT64_ARRAY_TYPE Bounds(Type::Array(cache.kAsmDouble, zone))
44 #define FUNC_I2I_ARRAY_TYPE \
45 Bounds(Type::Array(Type::Function(cache.kAsmSigned, cache.kAsmInt, zone), \
46 zone))
47
48 using namespace v8::internal;
49
50 namespace {
51
52 std::string Validate(Zone* zone, const char* source,
53 ZoneVector<ExpressionTypeEntry>* types) {
54 i::Isolate* isolate = CcTest::i_isolate();
55 i::Factory* factory = isolate->factory();
56
57 i::Handle<i::String> source_code =
58 factory->NewStringFromUtf8(i::CStrVector(source)).ToHandleChecked();
59
60 i::Handle<i::Script> script = factory->NewScript(source_code);
61
62 i::ParseInfo info(zone, script);
63 i::Parser parser(&info);
64 info.set_global();
65 info.set_lazy(false);
66 info.set_allow_lazy_parsing(false);
67 info.set_toplevel(true);
68
69 CHECK(i::Compiler::ParseAndAnalyze(&info));
70
71 FunctionLiteral* root =
72 info.scope()->declarations()->at(0)->AsFunctionDeclaration()->fun();
73 AsmTyper typer(isolate, zone, *script, root);
74 if (typer.Validate()) {
75 ExpressionTypeCollector(isolate, root, typer.bounds(), types).Run();
76 return "";
77 } else {
78 return typer.error_message();
79 }
80 }
81
82 } // namespace
83
84 TEST(ValidateMinimum) {
85 const char test_function[] =
86 "function GeometricMean(stdlib, foreign, buffer) {\n"
87 " \"use asm\";\n"
88 "\n"
89 " var exp = stdlib.Math.exp;\n"
90 " var log = stdlib.Math.log;\n"
91 " var values = new stdlib.Float64Array(buffer);\n"
92 "\n"
93 " function logSum(start, end) {\n"
94 " start = start|0;\n"
95 " end = end|0;\n"
96 "\n"
97 " var sum = 0.0, p = 0, q = 0;\n"
98 "\n"
99 " // asm.js forces byte addressing of the heap by requiring shifting "
100 "by 3\n"
101 " for (p = start << 3, q = end << 3; (p|0) < (q|0); p = (p + 8)|0) {\n"
102 " sum = sum + +log(values[p>>3]);\n"
103 " }\n"
104 "\n"
105 " return +sum;\n"
106 " }\n"
107 "\n"
108 " function geometricMean(start, end) {\n"
109 " start = start|0;\n"
110 " end = end|0;\n"
111 "\n"
112 " return +exp(+logSum(start, end) / +((end - start)|0));\n"
113 " }\n"
114 "\n"
115 " return { geometricMean: geometricMean };\n"
116 "}\n";
117
118 v8::V8::Initialize();
119 HandleAndZoneScope handles;
120 Zone* zone = handles.main_zone();
121 ZoneVector<ExpressionTypeEntry> types(zone);
122 CHECK_EQ("", Validate(zone, test_function, &types));
123 TypeCache cache;
124
125 CHECK_TYPES_BEGIN {
126 // Module.
127 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
128 // function logSum
129 CHECK_EXPR(FunctionLiteral, FUNC_II2D_TYPE) {
130 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
131 CHECK_VAR(start, Bounds(cache.kAsmInt));
132 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
133 CHECK_VAR(start, Bounds(cache.kAsmInt));
134 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
135 }
136 }
137 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
138 CHECK_VAR(end, Bounds(cache.kAsmInt));
139 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
140 CHECK_VAR(end, Bounds(cache.kAsmInt));
141 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
142 }
143 }
144 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
145 CHECK_VAR(sum, Bounds(cache.kAsmDouble));
146 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
147 }
148 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
149 CHECK_VAR(p, Bounds(cache.kAsmInt));
150 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
151 }
152 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
153 CHECK_VAR(q, Bounds(cache.kAsmInt));
154 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
155 }
156 // for (p = start << 3, q = end << 3;
157 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
158 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
159 CHECK_VAR(p, Bounds(cache.kAsmInt));
160 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
161 CHECK_VAR(start, Bounds(cache.kAsmInt));
162 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
163 }
164 }
165 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
166 CHECK_VAR(q, Bounds(cache.kAsmInt));
167 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
168 CHECK_VAR(end, Bounds(cache.kAsmInt));
169 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
170 }
171 }
172 }
173 // (p|0) < (q|0);
174 CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
175 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
176 CHECK_VAR(p, Bounds(cache.kAsmInt));
177 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
178 }
179 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
180 CHECK_VAR(q, Bounds(cache.kAsmInt));
181 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
182 }
183 }
184 // p = (p + 8)|0) {
185 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
186 CHECK_VAR(p, Bounds(cache.kAsmInt));
187 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
188 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
189 CHECK_VAR(p, Bounds(cache.kAsmInt));
190 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
191 }
192 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
193 }
194 }
195 // sum = sum + +log(values[p>>3]);
196 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
197 CHECK_VAR(sum, Bounds(cache.kAsmDouble));
198 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
199 CHECK_VAR(sum, Bounds(cache.kAsmDouble));
200 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
201 CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
202 CHECK_VAR(log, FUNC_D2D_TYPE);
203 CHECK_EXPR(Property, Bounds(cache.kAsmDouble)) {
204 CHECK_VAR(values, FLOAT64_ARRAY_TYPE);
205 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
206 CHECK_VAR(p, Bounds(cache.kAsmInt));
207 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
208 }
209 }
210 }
211 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
212 }
213 }
214 }
215 // return +sum;
216 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
217 CHECK_VAR(sum, Bounds(cache.kAsmDouble));
218 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
219 }
220 }
221 // function geometricMean
222 CHECK_EXPR(FunctionLiteral, FUNC_II2D_TYPE) {
223 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
224 CHECK_VAR(start, Bounds(cache.kAsmInt));
225 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
226 CHECK_VAR(start, Bounds(cache.kAsmInt));
227 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
228 }
229 }
230 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
231 CHECK_VAR(end, Bounds(cache.kAsmInt));
232 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
233 CHECK_VAR(end, Bounds(cache.kAsmInt));
234 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
235 }
236 }
237 // return +exp(+logSum(start, end) / +((end - start)|0));
238 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
239 CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
240 CHECK_VAR(exp, FUNC_D2D_TYPE);
241 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
242 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
243 CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
244 CHECK_VAR(logSum, FUNC_II2D_TYPE);
245 CHECK_VAR(start, Bounds(cache.kAsmInt));
246 CHECK_VAR(end, Bounds(cache.kAsmInt));
247 }
248 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
249 }
250 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
251 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
252 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
253 CHECK_VAR(end, Bounds(cache.kAsmInt));
254 CHECK_VAR(start, Bounds(cache.kAsmInt));
255 }
256 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
257 }
258 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
259 }
260 }
261 }
262 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
263 }
264 }
265 // "use asm";
266 CHECK_EXPR(Literal, Bounds(Type::String()));
267 // var exp = stdlib.Math.exp;
268 CHECK_EXPR(Assignment, FUNC_D2D_TYPE) {
269 CHECK_VAR(exp, FUNC_D2D_TYPE);
270 CHECK_EXPR(Property, FUNC_D2D_TYPE) {
271 CHECK_EXPR(Property, Bounds::Unbounded()) {
272 CHECK_VAR(stdlib, Bounds::Unbounded());
273 CHECK_EXPR(Literal, Bounds::Unbounded());
274 }
275 CHECK_EXPR(Literal, Bounds::Unbounded());
276 }
277 }
278 // var log = stdlib.Math.log;
279 CHECK_EXPR(Assignment, FUNC_D2D_TYPE) {
280 CHECK_VAR(log, FUNC_D2D_TYPE);
281 CHECK_EXPR(Property, FUNC_D2D_TYPE) {
282 CHECK_EXPR(Property, Bounds::Unbounded()) {
283 CHECK_VAR(stdlib, Bounds::Unbounded());
284 CHECK_EXPR(Literal, Bounds::Unbounded());
285 }
286 CHECK_EXPR(Literal, Bounds::Unbounded());
287 }
288 }
289 // var values = new stdlib.Float64Array(buffer);
290 CHECK_EXPR(Assignment, FLOAT64_ARRAY_TYPE) {
291 CHECK_VAR(values, FLOAT64_ARRAY_TYPE);
292 CHECK_EXPR(CallNew, FLOAT64_ARRAY_TYPE) {
293 CHECK_EXPR(Property, Bounds::Unbounded()) {
294 CHECK_VAR(stdlib, Bounds::Unbounded());
295 CHECK_EXPR(Literal, Bounds::Unbounded());
296 }
297 CHECK_VAR(buffer, Bounds::Unbounded());
298 }
299 }
300 // return { geometricMean: geometricMean };
301 CHECK_EXPR(ObjectLiteral, Bounds::Unbounded()) {
302 CHECK_VAR(geometricMean, FUNC_II2D_TYPE);
303 }
304 }
305 }
306 CHECK_TYPES_END
307 }
308
309 TEST(MissingUseAsm) {
310 const char test_function[] =
311 "function foo() {\n"
312 " function bar() {}\n"
313 " return { bar: bar };\n"
314 "}\n";
315 v8::V8::Initialize();
316 HandleAndZoneScope handles;
317 Zone* zone = handles.main_zone();
318 ZoneVector<ExpressionTypeEntry> types(zone);
319 CHECK_EQ("asm: line 1: missing \"use asm\"\n",
320 Validate(zone, test_function, &types));
321 }
322
323 TEST(WrongUseAsm) {
324 const char test_function[] =
325 "function foo() {\n"
326 " \"use wasm\"\n"
327 " function bar() {}\n"
328 " return { bar: bar };\n"
329 "}\n";
330 v8::V8::Initialize();
331 HandleAndZoneScope handles;
332 Zone* zone = handles.main_zone();
333 ZoneVector<ExpressionTypeEntry> types(zone);
334 CHECK_EQ("asm: line 1: missing \"use asm\"\n",
335 Validate(zone, test_function, &types));
336 }
337
338 TEST(MissingReturnExports) {
339 const char test_function[] =
340 "function foo() {\n"
341 " \"use asm\"\n"
342 " function bar() {}\n"
343 "}\n";
344 v8::V8::Initialize();
345 HandleAndZoneScope handles;
346 Zone* zone = handles.main_zone();
347 ZoneVector<ExpressionTypeEntry> types(zone);
348 CHECK_EQ("asm: line 2: last statement in module is not a return\n",
349 Validate(zone, test_function, &types));
350 }
351
352 #define HARNESS_STDLIB() \
353 "var Infinity = stdlib.Infinity; " \
354 "var NaN = stdlib.NaN; " \
355 "var acos = stdlib.Math.acos; " \
356 "var asin = stdlib.Math.asin; " \
357 "var atan = stdlib.Math.atan; " \
358 "var cos = stdlib.Math.cos; " \
359 "var sin = stdlib.Math.sin; " \
360 "var tan = stdlib.Math.tan; " \
361 "var exp = stdlib.Math.exp; " \
362 "var log = stdlib.Math.log; " \
363 "var ceil = stdlib.Math.ceil; " \
364 "var floor = stdlib.Math.floor; " \
365 "var sqrt = stdlib.Math.sqrt; " \
366 "var min = stdlib.Math.min; " \
367 "var max = stdlib.Math.max; " \
368 "var atan2 = stdlib.Math.atan2; " \
369 "var pow = stdlib.Math.pow; " \
370 "var abs = stdlib.Math.abs; " \
371 "var imul = stdlib.Math.imul; " \
372 "var fround = stdlib.Math.fround; " \
373 "var E = stdlib.Math.E; " \
374 "var LN10 = stdlib.Math.LN10; " \
375 "var LN2 = stdlib.Math.LN2; " \
376 "var LOG2E = stdlib.Math.LOG2E; " \
377 "var LOG10E = stdlib.Math.LOG10E; " \
378 "var PI = stdlib.Math.PI; " \
379 "var SQRT1_2 = stdlib.Math.SQRT1_2; " \
380 "var SQRT2 = stdlib.Math.SQRT2; "
381
382 #define HARNESS_HEAP() \
383 "var u8 = new stdlib.Uint8Array(buffer); " \
384 "var i8 = new stdlib.Int8Array(buffer); " \
385 "var u16 = new stdlib.Uint16Array(buffer); " \
386 "var i16 = new stdlib.Int16Array(buffer); " \
387 "var u32 = new stdlib.Uint32Array(buffer); " \
388 "var i32 = new stdlib.Int32Array(buffer); " \
389 "var f32 = new stdlib.Float32Array(buffer); " \
390 "var f64 = new stdlib.Float64Array(buffer); "
391
392 #define HARNESS_PREAMBLE() \
393 const char test_function[] = \
394 "function Module(stdlib, foreign, buffer) { " \
395 "\"use asm\"; " HARNESS_STDLIB() HARNESS_HEAP()
396
397 #define HARNESS_POSTAMBLE() \
398 "return { foo: foo }; " \
399 "} ";
400
401 #define CHECK_VAR_MATH_SHORTCUT(name, type) \
402 CHECK_EXPR(Assignment, type) { \
403 CHECK_VAR(name, type); \
404 CHECK_EXPR(Property, type) { \
405 CHECK_EXPR(Property, Bounds::Unbounded()) { \
406 CHECK_VAR(stdlib, Bounds::Unbounded()); \
407 CHECK_EXPR(Literal, Bounds::Unbounded()); \
408 } \
409 CHECK_EXPR(Literal, Bounds::Unbounded()); \
410 } \
411 }
412
413 #define CHECK_VAR_SHORTCUT(name, type) \
414 CHECK_EXPR(Assignment, type) { \
415 CHECK_VAR(name, type); \
416 CHECK_EXPR(Property, type) { \
417 CHECK_VAR(stdlib, Bounds::Unbounded()); \
418 CHECK_EXPR(Literal, Bounds::Unbounded()); \
419 } \
420 }
421
422 #define CHECK_VAR_NEW_SHORTCUT(name, type) \
423 CHECK_EXPR(Assignment, type) { \
424 CHECK_VAR(name, type); \
425 CHECK_EXPR(CallNew, type) { \
426 CHECK_EXPR(Property, Bounds::Unbounded()) { \
427 CHECK_VAR(stdlib, Bounds::Unbounded()); \
428 CHECK_EXPR(Literal, Bounds::Unbounded()); \
429 } \
430 CHECK_VAR(buffer, Bounds::Unbounded()); \
431 } \
432 }
433
434 namespace {
435
436 void CheckStdlibShortcuts1(Zone* zone, ZoneVector<ExpressionTypeEntry>& types,
437 size_t& index, int& depth, TypeCache& cache) {
438 // var exp = stdlib.*;
439 CHECK_VAR_SHORTCUT(Infinity, Bounds(cache.kAsmDouble));
440 CHECK_VAR_SHORTCUT(NaN, Bounds(cache.kAsmDouble));
441 // var x = stdlib.Math.x;
442 CHECK_VAR_MATH_SHORTCUT(acos, FUNC_D2D_TYPE);
443 CHECK_VAR_MATH_SHORTCUT(asin, FUNC_D2D_TYPE);
444 CHECK_VAR_MATH_SHORTCUT(atan, FUNC_D2D_TYPE);
445 CHECK_VAR_MATH_SHORTCUT(cos, FUNC_D2D_TYPE);
446 CHECK_VAR_MATH_SHORTCUT(sin, FUNC_D2D_TYPE);
447 CHECK_VAR_MATH_SHORTCUT(tan, FUNC_D2D_TYPE);
448 CHECK_VAR_MATH_SHORTCUT(exp, FUNC_D2D_TYPE);
449 CHECK_VAR_MATH_SHORTCUT(log, FUNC_D2D_TYPE);
450
451 CHECK_VAR_MATH_SHORTCUT(ceil, FUNC_N2N_TYPE);
452 CHECK_VAR_MATH_SHORTCUT(floor, FUNC_N2N_TYPE);
453 CHECK_VAR_MATH_SHORTCUT(sqrt, FUNC_N2N_TYPE);
454
455 CHECK_VAR_MATH_SHORTCUT(min, FUNC_NN2N_TYPE);
456 CHECK_VAR_MATH_SHORTCUT(max, FUNC_NN2N_TYPE);
457
458 CHECK_VAR_MATH_SHORTCUT(atan2, FUNC_DD2D_TYPE);
459 CHECK_VAR_MATH_SHORTCUT(pow, FUNC_DD2D_TYPE);
460
461 CHECK_VAR_MATH_SHORTCUT(abs, FUNC_N2N_TYPE);
462 CHECK_VAR_MATH_SHORTCUT(imul, FUNC_II2I_TYPE);
463 CHECK_VAR_MATH_SHORTCUT(fround, FUNC_N2F_TYPE);
464 }
465
466 void CheckStdlibShortcuts2(Zone* zone, ZoneVector<ExpressionTypeEntry>& types,
467 size_t& index, int& depth, TypeCache& cache) {
468 // var exp = stdlib.Math.*; (D * 12)
469 CHECK_VAR_MATH_SHORTCUT(E, Bounds(cache.kAsmDouble));
470 CHECK_VAR_MATH_SHORTCUT(LN10, Bounds(cache.kAsmDouble));
471 CHECK_VAR_MATH_SHORTCUT(LN2, Bounds(cache.kAsmDouble));
472 CHECK_VAR_MATH_SHORTCUT(LOG2E, Bounds(cache.kAsmDouble));
473 CHECK_VAR_MATH_SHORTCUT(LOG10E, Bounds(cache.kAsmDouble));
474 CHECK_VAR_MATH_SHORTCUT(PI, Bounds(cache.kAsmDouble));
475 CHECK_VAR_MATH_SHORTCUT(SQRT1_2, Bounds(cache.kAsmDouble));
476 CHECK_VAR_MATH_SHORTCUT(SQRT2, Bounds(cache.kAsmDouble));
477 // var values = new stdlib.*Array(buffer);
478 CHECK_VAR_NEW_SHORTCUT(u8, Bounds(cache.kUint8Array));
479 CHECK_VAR_NEW_SHORTCUT(i8, Bounds(cache.kInt8Array));
480 CHECK_VAR_NEW_SHORTCUT(u16, Bounds(cache.kUint16Array));
481 CHECK_VAR_NEW_SHORTCUT(i16, Bounds(cache.kInt16Array));
482 CHECK_VAR_NEW_SHORTCUT(u32, Bounds(cache.kUint32Array));
483 CHECK_VAR_NEW_SHORTCUT(i32, Bounds(cache.kInt32Array));
484 CHECK_VAR_NEW_SHORTCUT(f32, Bounds(cache.kFloat32Array));
485 CHECK_VAR_NEW_SHORTCUT(f64, Bounds(cache.kFloat64Array));
486 }
487
488 } // namespace
489
490 #define CHECK_FUNC_TYPES_BEGIN(func) \
491 HARNESS_PREAMBLE() \
492 func "\n" HARNESS_POSTAMBLE(); \
493 \
494 v8::V8::Initialize(); \
495 HandleAndZoneScope handles; \
496 Zone* zone = handles.main_zone(); \
497 ZoneVector<ExpressionTypeEntry> types(zone); \
498 CHECK_EQ("", Validate(zone, test_function, &types)); \
499 TypeCache cache; \
500 \
501 CHECK_TYPES_BEGIN { \
502 /* Module. */ \
503 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
504 #define CHECK_FUNC_TYPES_END_1() \
505 /* "use asm"; */ \
506 CHECK_EXPR(Literal, Bounds(Type::String())); \
507 /* stdlib shortcuts. */ \
508 CheckStdlibShortcuts1(zone, types, index, depth, cache); \
509 CheckStdlibShortcuts2(zone, types, index, depth, cache);
510
511 #define CHECK_FUNC_TYPES_END_2() \
512 /* return { foo: foo }; */ \
513 CHECK_EXPR(ObjectLiteral, Bounds::Unbounded()) { \
514 CHECK_VAR(foo, FUNC_V_TYPE); \
515 } \
516 } \
517 } \
518 CHECK_TYPES_END
519
520 #define CHECK_FUNC_TYPES_END \
521 CHECK_FUNC_TYPES_END_1(); \
522 CHECK_FUNC_TYPES_END_2();
523
524 #define CHECK_FUNC_ERROR(func, message) \
525 HARNESS_PREAMBLE() \
526 func "\n" HARNESS_POSTAMBLE(); \
527 \
528 v8::V8::Initialize(); \
529 HandleAndZoneScope handles; \
530 Zone* zone = handles.main_zone(); \
531 ZoneVector<ExpressionTypeEntry> types(zone); \
532 CHECK_EQ(message, Validate(zone, test_function, &types));
533
534 TEST(BareHarness) {
535 CHECK_FUNC_TYPES_BEGIN("function foo() {}") {
536 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {}
537 }
538 CHECK_FUNC_TYPES_END
539 }
540
541 TEST(ReturnVoid) {
542 CHECK_FUNC_TYPES_BEGIN(
543 "function bar() { return; }\n"
544 "function foo() { bar(); }") {
545 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
546 // return undefined;
547 CHECK_EXPR(Literal, Bounds(Type::Undefined()));
548 }
549 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
550 CHECK_EXPR(Call, Bounds(Type::Undefined())) {
551 CHECK_VAR(bar, FUNC_V_TYPE);
552 }
553 }
554 }
555 CHECK_FUNC_TYPES_END
556 }
557
558 TEST(EmptyBody) {
559 CHECK_FUNC_TYPES_BEGIN(
560 "function bar() { }\n"
561 "function foo() { bar(); }") {
562 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE);
563 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
564 CHECK_EXPR(Call, Bounds(Type::Undefined())) {
565 CHECK_VAR(bar, FUNC_V_TYPE);
566 }
567 }
568 }
569 CHECK_FUNC_TYPES_END
570 }
571
572 TEST(DoesNothing) {
573 CHECK_FUNC_TYPES_BEGIN(
574 "function bar() { var x = 1.0; }\n"
575 "function foo() { bar(); }") {
576 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
577 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
578 CHECK_VAR(x, Bounds(cache.kAsmDouble));
579 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
580 }
581 }
582 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
583 CHECK_EXPR(Call, Bounds(Type::Undefined())) {
584 CHECK_VAR(bar, FUNC_V_TYPE);
585 }
586 }
587 }
588 CHECK_FUNC_TYPES_END
589 }
590
591 TEST(ReturnInt32Literal) {
592 CHECK_FUNC_TYPES_BEGIN(
593 "function bar() { return 1; }\n"
594 "function foo() { bar(); }") {
595 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
596 // return 1;
597 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
598 }
599 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
600 CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
601 CHECK_VAR(bar, FUNC_I_TYPE);
602 }
603 }
604 }
605 CHECK_FUNC_TYPES_END
606 }
607
608 TEST(ReturnFloat64Literal) {
609 CHECK_FUNC_TYPES_BEGIN(
610 "function bar() { return 1.0; }\n"
611 "function foo() { bar(); }") {
612 CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) {
613 // return 1.0;
614 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
615 }
616 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
617 CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
618 CHECK_VAR(bar, FUNC_D_TYPE);
619 }
620 }
621 }
622 CHECK_FUNC_TYPES_END
623 }
624
625 TEST(ReturnFloat32Literal) {
626 CHECK_FUNC_TYPES_BEGIN(
627 "function bar() { return fround(1.0); }\n"
628 "function foo() { bar(); }") {
629 CHECK_EXPR(FunctionLiteral, FUNC_F_TYPE) {
630 // return fround(1.0);
631 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
632 CHECK_VAR(fround, FUNC_N2F_TYPE);
633 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
634 }
635 }
636 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
637 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) { CHECK_VAR(bar, FUNC_F_TYPE); }
638 }
639 }
640 CHECK_FUNC_TYPES_END
641 }
642
643 TEST(ReturnFloat64Var) {
644 CHECK_FUNC_TYPES_BEGIN(
645 "function bar() { var x = 1.0; return +x; }\n"
646 "function foo() { bar(); }") {
647 CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) {
648 // return 1.0;
649 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
650 CHECK_VAR(x, Bounds(cache.kAsmDouble));
651 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
652 }
653 // return 1.0;
654 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
655 CHECK_VAR(x, Bounds(cache.kAsmDouble));
656 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
657 }
658 }
659 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
660 CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
661 CHECK_VAR(bar, FUNC_D_TYPE);
662 }
663 }
664 }
665 CHECK_FUNC_TYPES_END
666 }
667
668 TEST(Addition2) {
669 CHECK_FUNC_TYPES_BEGIN(
670 "function bar() { var x = 1; var y = 2; return (x+y)|0; }\n"
671 "function foo() { bar(); }") {
672 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
673 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
674 CHECK_VAR(x, Bounds(cache.kAsmInt));
675 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
676 }
677 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
678 CHECK_VAR(y, Bounds(cache.kAsmInt));
679 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
680 }
681 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
682 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
683 CHECK_VAR(x, Bounds(cache.kAsmInt));
684 CHECK_VAR(y, Bounds(cache.kAsmInt));
685 }
686 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
687 }
688 }
689 CHECK_SKIP();
690 }
691 CHECK_FUNC_TYPES_END
692 }
693
694 #define TEST_COMPARE_OP(name, op) \
695 TEST(name) { \
696 CHECK_FUNC_TYPES_BEGIN("function bar() { return (0 " op \
697 " 0)|0; }\n" \
698 "function foo() { bar(); }") { \
699 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { \
700 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { \
701 CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) { \
702 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \
703 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \
704 } \
705 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \
706 } \
707 } \
708 CHECK_SKIP(); \
709 } \
710 CHECK_FUNC_TYPES_END \
711 }
712
713 TEST_COMPARE_OP(EqOperator, "==")
714 TEST_COMPARE_OP(LtOperator, "<")
715 TEST_COMPARE_OP(LteOperator, "<=")
716 TEST_COMPARE_OP(GtOperator, ">")
717 TEST_COMPARE_OP(GteOperator, ">=")
718
719 TEST(NeqOperator) {
720 CHECK_FUNC_TYPES_BEGIN(
721 "function bar() { return (0 != 0)|0; }\n"
722 "function foo() { bar(); }") {
723 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
724 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
725 CHECK_EXPR(UnaryOperation, Bounds(cache.kAsmSigned)) {
726 CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
727 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
728 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
729 }
730 }
731 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
732 }
733 }
734 CHECK_SKIP();
735 }
736 CHECK_FUNC_TYPES_END
737 }
738
739 TEST(NotOperator) {
740 CHECK_FUNC_TYPES_BEGIN(
741 "function bar() { var x = 0; return (!x)|0; }\n"
742 "function foo() { bar(); }") {
743 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
744 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
745 CHECK_VAR(x, Bounds(cache.kAsmInt));
746 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
747 }
748 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
749 CHECK_EXPR(UnaryOperation, Bounds(cache.kAsmSigned)) {
750 CHECK_VAR(x, Bounds(cache.kAsmInt));
751 }
752 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
753 }
754 }
755 CHECK_SKIP();
756 }
757 CHECK_FUNC_TYPES_END
758 }
759
760 TEST(InvertOperator) {
761 CHECK_FUNC_TYPES_BEGIN(
762 "function bar() { var x = 0; return (~x)|0; }\n"
763 "function foo() { bar(); }") {
764 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
765 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
766 CHECK_VAR(x, Bounds(cache.kAsmInt));
767 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
768 }
769 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
770 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
771 CHECK_VAR(x, Bounds(cache.kAsmInt));
772 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
773 }
774 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
775 }
776 }
777 CHECK_SKIP();
778 }
779 CHECK_FUNC_TYPES_END
780 }
781
782 TEST(InvertConversion) {
783 CHECK_FUNC_TYPES_BEGIN(
784 "function bar() { var x = 0.0; return (~~x)|0; }\n"
785 "function foo() { bar(); }") {
786 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
787 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
788 CHECK_VAR(x, Bounds(cache.kAsmDouble));
789 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
790 }
791 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
792 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
793 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
794 CHECK_VAR(x, Bounds(cache.kAsmDouble));
795 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
796 }
797 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
798 }
799 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
800 }
801 }
802 CHECK_SKIP();
803 }
804 CHECK_FUNC_TYPES_END
805 }
806
807 TEST(Ternary) {
808 CHECK_FUNC_TYPES_BEGIN(
809 "function bar() { var x = 1; var y = 1; return (x?y:5)|0; }\n"
810 "function foo() { bar(); }") {
811 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
812 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
813 CHECK_VAR(x, Bounds(cache.kAsmInt));
814 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
815 }
816 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
817 CHECK_VAR(y, Bounds(cache.kAsmInt));
818 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
819 }
820 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
821 CHECK_EXPR(Conditional, Bounds(cache.kAsmInt)) {
822 CHECK_VAR(x, Bounds(cache.kAsmInt));
823 CHECK_VAR(y, Bounds(cache.kAsmInt));
824 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
825 }
826 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
827 }
828 }
829 CHECK_SKIP();
830 }
831 CHECK_FUNC_TYPES_END
832 }
833
834 #define TEST_INT_BIN_OP(name, op) \
835 TEST(name) { \
836 CHECK_FUNC_TYPES_BEGIN("function bar() { var x = 0; return (x " op \
837 " 123)|0; }\n" \
838 "function foo() { bar(); }") { \
839 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { \
840 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { \
841 CHECK_VAR(x, Bounds(cache.kAsmInt)); \
842 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \
843 } \
844 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { \
845 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { \
846 CHECK_VAR(x, Bounds(cache.kAsmInt)); \
847 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \
848 } \
849 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \
850 } \
851 } \
852 CHECK_SKIP(); \
853 } \
854 CHECK_FUNC_TYPES_END \
855 }
856
857 TEST_INT_BIN_OP(AndOperator, "&")
858 TEST_INT_BIN_OP(OrOperator, "|")
859 TEST_INT_BIN_OP(XorOperator, "^")
860
861 TEST(SignedCompare) {
862 CHECK_FUNC_TYPES_BEGIN(
863 "function bar() { var x = 1; var y = 1; return ((x|0) < (y|0))|0; }\n"
864 "function foo() { bar(); }") {
865 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
866 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
867 CHECK_VAR(x, Bounds(cache.kAsmInt));
868 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
869 }
870 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
871 CHECK_VAR(y, Bounds(cache.kAsmInt));
872 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
873 }
874 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
875 CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
876 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
877 CHECK_VAR(x, Bounds(cache.kAsmInt));
878 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
879 }
880 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
881 CHECK_VAR(y, Bounds(cache.kAsmInt));
882 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
883 }
884 }
885 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
886 }
887 }
888 CHECK_SKIP();
889 }
890 CHECK_FUNC_TYPES_END
891 }
892
893 TEST(SignedCompareConst) {
894 CHECK_FUNC_TYPES_BEGIN(
895 "function bar() { var x = 1; var y = 1; return ((x|0) < (1<<31))|0; }\n"
896 "function foo() { bar(); }") {
897 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
898 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
899 CHECK_VAR(x, Bounds(cache.kAsmInt));
900 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
901 }
902 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
903 CHECK_VAR(y, Bounds(cache.kAsmInt));
904 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
905 }
906 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
907 CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
908 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
909 CHECK_VAR(x, Bounds(cache.kAsmInt));
910 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
911 }
912 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
913 }
914 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
915 }
916 }
917 CHECK_SKIP();
918 }
919 CHECK_FUNC_TYPES_END
920 }
921
922 TEST(UnsignedCompare) {
923 CHECK_FUNC_TYPES_BEGIN(
924 "function bar() { var x = 1; var y = 1; return ((x>>>0) < (y>>>0))|0; }\n"
925 "function foo() { bar(); }") {
926 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
927 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
928 CHECK_VAR(x, Bounds(cache.kAsmInt));
929 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
930 }
931 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
932 CHECK_VAR(y, Bounds(cache.kAsmInt));
933 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
934 }
935 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
936 CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
937 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
938 CHECK_VAR(x, Bounds(cache.kAsmInt));
939 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
940 }
941 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
942 CHECK_VAR(y, Bounds(cache.kAsmInt));
943 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
944 }
945 }
946 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
947 }
948 }
949 CHECK_SKIP();
950 }
951 CHECK_FUNC_TYPES_END
952 }
953
954 TEST(UnsignedCompareConst0) {
955 CHECK_FUNC_TYPES_BEGIN(
956 "function bar() { var x = 1; var y = 1; return ((x>>>0) < (0>>>0))|0; }\n"
957 "function foo() { bar(); }") {
958 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
959 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
960 CHECK_VAR(x, Bounds(cache.kAsmInt));
961 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
962 }
963 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
964 CHECK_VAR(y, Bounds(cache.kAsmInt));
965 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
966 }
967 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
968 CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
969 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
970 CHECK_VAR(x, Bounds(cache.kAsmInt));
971 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
972 }
973 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
974 }
975 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
976 }
977 }
978 CHECK_SKIP();
979 }
980 CHECK_FUNC_TYPES_END
981 }
982
983 TEST(UnsignedCompareConst1) {
984 CHECK_FUNC_TYPES_BEGIN(
985 "function bar() { var x = 1; var y = 1; return ((x>>>0) < "
986 "(0xffffffff>>>0))|0; }\n"
987 "function foo() { bar(); }") {
988 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
989 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
990 CHECK_VAR(x, Bounds(cache.kAsmInt));
991 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
992 }
993 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
994 CHECK_VAR(y, Bounds(cache.kAsmInt));
995 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
996 }
997 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
998 CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
999 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
1000 CHECK_VAR(x, Bounds(cache.kAsmInt));
1001 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1002 }
1003 CHECK_EXPR(Literal, Bounds(cache.kAsmUnsigned));
1004 }
1005 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1006 }
1007 }
1008 CHECK_SKIP();
1009 }
1010 CHECK_FUNC_TYPES_END
1011 }
1012
1013 TEST(UnsignedDivide) {
1014 CHECK_FUNC_TYPES_BEGIN(
1015 "function bar() { var x = 1; var y = 1; return ((x>>>0) / (y>>>0))|0; }\n"
1016 "function foo() { bar(); }") {
1017 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
1018 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1019 CHECK_VAR(x, Bounds(cache.kAsmInt));
1020 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1021 }
1022 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1023 CHECK_VAR(y, Bounds(cache.kAsmInt));
1024 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1025 }
1026 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1027 CHECK_EXPR(BinaryOperation, Bounds(Type::None(), Type::Any())) {
1028 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
1029 CHECK_VAR(x, Bounds(cache.kAsmInt));
1030 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1031 }
1032 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
1033 CHECK_VAR(y, Bounds(cache.kAsmInt));
1034 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1035 }
1036 }
1037 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1038 }
1039 }
1040 CHECK_SKIP();
1041 }
1042 CHECK_FUNC_TYPES_END
1043 }
1044
1045 TEST(UnsignedFromFloat64) {
1046 CHECK_FUNC_ERROR(
1047 "function bar() { var x = 1.0; return (x>>>0)|0; }\n"
1048 "function foo() { bar(); }",
1049 "asm: line 1: left bitwise operand expected to be an integer\n");
1050 }
1051
1052 TEST(AndFloat64) {
1053 CHECK_FUNC_ERROR(
1054 "function bar() { var x = 1.0; return (x&0)|0; }\n"
1055 "function foo() { bar(); }",
1056 "asm: line 1: left bitwise operand expected to be an integer\n");
1057 }
1058
1059 TEST(TypeMismatchAddInt32Float64) {
1060 CHECK_FUNC_ERROR(
1061 "function bar() { var x = 1.0; var y = 0; return (x + y)|0; }\n"
1062 "function foo() { bar(); }",
1063 "asm: line 1: ill-typed arithmetic operation\n");
1064 }
1065
1066 TEST(TypeMismatchSubInt32Float64) {
1067 CHECK_FUNC_ERROR(
1068 "function bar() { var x = 1.0; var y = 0; return (x - y)|0; }\n"
1069 "function foo() { bar(); }",
1070 "asm: line 1: ill-typed arithmetic operation\n");
1071 }
1072
1073 TEST(TypeMismatchDivInt32Float64) {
1074 CHECK_FUNC_ERROR(
1075 "function bar() { var x = 1.0; var y = 0; return (x / y)|0; }\n"
1076 "function foo() { bar(); }",
1077 "asm: line 1: ill-typed arithmetic operation\n");
1078 }
1079
1080 TEST(TypeMismatchModInt32Float64) {
1081 CHECK_FUNC_ERROR(
1082 "function bar() { var x = 1.0; var y = 0; return (x % y)|0; }\n"
1083 "function foo() { bar(); }",
1084 "asm: line 1: ill-typed arithmetic operation\n");
1085 }
1086
1087 TEST(ModFloat32) {
1088 CHECK_FUNC_ERROR(
1089 "function bar() { var x = fround(1.0); return (x % x)|0; }\n"
1090 "function foo() { bar(); }",
1091 "asm: line 1: ill-typed arithmetic operation\n");
1092 }
1093
1094 TEST(TernaryMismatchInt32Float64) {
1095 CHECK_FUNC_ERROR(
1096 "function bar() { var x = 1; var y = 0.0; return (1 ? x : y)|0; }\n"
1097 "function foo() { bar(); }",
1098 "asm: line 1: then and else expressions in ? must have the same type "
1099 "and be int, float, or double\n");
1100 }
1101
1102 TEST(TernaryMismatchIntish) {
1103 CHECK_FUNC_ERROR(
1104 "function bar() { var x = 1; var y = 0; return (1 ? x + x : y)|0; }\n"
1105 "function foo() { bar(); }",
1106 "asm: line 1: then and else expressions in ? must have the same type "
1107 "and be int, float, or double\n");
1108 }
1109
1110 TEST(TernaryMismatchInt32Float32) {
1111 CHECK_FUNC_ERROR(
1112 "function bar() { var x = 1; var y = 2.0; return (x?fround(y):x)|0; }\n"
1113 "function foo() { bar(); }",
1114 "asm: line 1: then and else expressions in ? must have the same type "
1115 "and be int, float, or double\n");
1116 }
1117
1118 TEST(TernaryBadCondition) {
1119 CHECK_FUNC_ERROR(
1120 "function bar() { var x = 1; var y = 2.0; return (y?x:1)|0; }\n"
1121 "function foo() { bar(); }",
1122 "asm: line 1: condition must be of type int\n");
1123 }
1124
1125 TEST(BadIntishMultiply) {
1126 CHECK_FUNC_ERROR(
1127 "function bar() { var x = 1; return ((x + x) * 4) | 0; }\n"
1128 "function foo() { bar(); }",
1129 "asm: line 1: intish not allowed in multiply\n");
1130 }
1131
1132 TEST(IntToFloat32) {
1133 CHECK_FUNC_ERROR(
1134 "function bar() { var x = 1; return fround(x); }\n"
1135 "function foo() { bar(); }",
1136 "asm: line 1: illegal function argument type\n");
1137 }
1138
1139 TEST(Int32ToFloat32) {
1140 CHECK_FUNC_TYPES_BEGIN(
1141 "function bar() { var x = 1; return fround(x|0); }\n"
1142 "function foo() { bar(); }") {
1143 CHECK_EXPR(FunctionLiteral, FUNC_F_TYPE) {
1144 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1145 CHECK_VAR(x, Bounds(cache.kAsmInt));
1146 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1147 }
1148 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
1149 CHECK_VAR(fround, FUNC_N2F_TYPE);
1150 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1151 CHECK_VAR(x, Bounds(cache.kAsmInt));
1152 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1153 }
1154 }
1155 }
1156 CHECK_SKIP();
1157 }
1158 CHECK_FUNC_TYPES_END
1159 }
1160
1161 TEST(Uint32ToFloat32) {
1162 CHECK_FUNC_TYPES_BEGIN(
1163 "function bar() { var x = 1; return fround(x>>>0); }\n"
1164 "function foo() { bar(); }") {
1165 CHECK_EXPR(FunctionLiteral, FUNC_F_TYPE) {
1166 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1167 CHECK_VAR(x, Bounds(cache.kAsmInt));
1168 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1169 }
1170 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
1171 CHECK_VAR(fround, FUNC_N2F_TYPE);
1172 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
1173 CHECK_VAR(x, Bounds(cache.kAsmInt));
1174 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1175 }
1176 }
1177 }
1178 CHECK_SKIP();
1179 }
1180 CHECK_FUNC_TYPES_END
1181 }
1182
1183 TEST(Float64ToFloat32) {
1184 CHECK_FUNC_TYPES_BEGIN(
1185 "function bar() { var x = 1.0; return fround(x); }\n"
1186 "function foo() { bar(); }") {
1187 CHECK_EXPR(FunctionLiteral, FUNC_F_TYPE) {
1188 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
1189 CHECK_VAR(x, Bounds(cache.kAsmDouble));
1190 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1191 }
1192 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
1193 CHECK_VAR(fround, FUNC_N2F_TYPE);
1194 CHECK_VAR(x, Bounds(cache.kAsmDouble));
1195 }
1196 }
1197 CHECK_SKIP();
1198 }
1199 CHECK_FUNC_TYPES_END
1200 }
1201
1202 TEST(Int32ToFloat32ToInt32) {
1203 CHECK_FUNC_TYPES_BEGIN(
1204 "function bar() { var x = 1; return ~~fround(x|0) | 0; }\n"
1205 "function foo() { bar(); }") {
1206 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
1207 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1208 CHECK_VAR(x, Bounds(cache.kAsmInt));
1209 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1210 }
1211 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1212 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1213 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1214 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
1215 CHECK_VAR(fround, FUNC_N2F_TYPE);
1216 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1217 CHECK_VAR(x, Bounds(cache.kAsmInt));
1218 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1219 }
1220 }
1221 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
1222 }
1223 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
1224 }
1225 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1226 }
1227 }
1228 CHECK_SKIP();
1229 }
1230 CHECK_FUNC_TYPES_END
1231 }
1232
1233 TEST(Addition4) {
1234 CHECK_FUNC_TYPES_BEGIN(
1235 "function bar() { var x = 1; var y = 2; return (x+y+x+y)|0; }\n"
1236 "function foo() { bar(); }") {
1237 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
1238 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1239 CHECK_VAR(x, Bounds(cache.kAsmInt));
1240 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1241 }
1242 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1243 CHECK_VAR(y, Bounds(cache.kAsmInt));
1244 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1245 }
1246 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1247 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
1248 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
1249 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
1250 CHECK_VAR(x, Bounds(cache.kAsmInt));
1251 CHECK_VAR(y, Bounds(cache.kAsmInt));
1252 }
1253 CHECK_VAR(x, Bounds(cache.kAsmInt));
1254 }
1255 CHECK_VAR(y, Bounds(cache.kAsmInt));
1256 }
1257 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1258 }
1259 }
1260 CHECK_SKIP();
1261 }
1262 CHECK_FUNC_TYPES_END
1263 }
1264
1265 TEST(Multiplication2) {
1266 CHECK_FUNC_ERROR(
1267 "function bar() { var x = 1; var y = 2; return (x*y)|0; }\n"
1268 "function foo() { bar(); }",
1269 "asm: line 1: multiply must be by an integer literal\n");
1270 }
1271
1272 TEST(Division4) {
1273 CHECK_FUNC_ERROR(
1274 "function bar() { var x = 1; var y = 2; return (x/y/x/y)|0; }\n"
1275 "function foo() { bar(); }",
1276 "asm: line 1: left and right side of integer / or % "
1277 "must match and be signed or unsigned\n");
1278 }
1279
1280 TEST(ModInt) {
1281 CHECK_FUNC_ERROR(
1282 "function bar() { var x = 1; var y = 2; return (x%y)|0; }\n"
1283 "function foo() { bar(); }",
1284 "asm: line 1: left and right side of integer / or % "
1285 "must match and be signed or unsigned\n");
1286 }
1287
1288 TEST(DivInt) {
1289 CHECK_FUNC_ERROR(
1290 "function bar() { var x = 1; var y = 2; return (x/y)|0; }\n"
1291 "function foo() { bar(); }",
1292 "asm: line 1: left and right side of integer / or % "
1293 "must match and be signed or unsigned\n");
1294 }
1295
1296 TEST(ModIntMismatch) {
1297 CHECK_FUNC_ERROR(
1298 "function bar() { var x = 1; var y = 2; return ((x|0)%(y>>>0))|0; }\n"
1299 "function foo() { bar(); }",
1300 "asm: line 1: left and right side of integer / or % "
1301 "must match and be signed or unsigned\n");
1302 }
1303
1304 TEST(DivIntMismatch) {
1305 CHECK_FUNC_ERROR(
1306 "function bar() { var x = 1; var y = 2; return ((x|0)/(y>>>0))|0; }\n"
1307 "function foo() { bar(); }",
1308 "asm: line 1: left and right side of integer / or % "
1309 "must match and be signed or unsigned\n");
1310 }
1311
1312 TEST(CompareToStringLeft) {
1313 CHECK_FUNC_ERROR(
1314 "function bar() { var x = 1; return ('hi' > x)|0; }\n"
1315 "function foo() { bar(); }",
1316 "asm: line 1: left and right side of comparison must match type "
1317 "and be signed, unsigned, float, or double\n");
1318 }
1319
1320 TEST(CompareToStringRight) {
1321 CHECK_FUNC_ERROR(
1322 "function bar() { var x = 1; return (x < 'hi')|0; }\n"
1323 "function foo() { bar(); }",
1324 "asm: line 1: left and right side of comparison must match type "
1325 "and be signed, unsigned, float, or double\n");
1326 }
1327
1328 TEST(CompareMismatchInt32Float64) {
1329 CHECK_FUNC_ERROR(
1330 "function bar() { var x = 1; var y = 2.0; return (x < y)|0; }\n"
1331 "function foo() { bar(); }",
1332 "asm: line 1: left and right side of comparison must match type "
1333 "and be signed, unsigned, float, or double\n");
1334 }
1335
1336 TEST(CompareMismatchInt32Uint32) {
1337 CHECK_FUNC_ERROR(
1338 "function bar() { var x = 1; var y = 2; return ((x|0) < (y>>>0))|0; }\n"
1339 "function foo() { bar(); }",
1340 "asm: line 1: left and right side of comparison must match type "
1341 "and be signed, unsigned, float, or double\n");
1342 }
1343
1344 TEST(CompareMismatchInt32Float32) {
1345 CHECK_FUNC_ERROR(
1346 "function bar() { var x = 1; var y = 2.0; return (x < fround(y))|0; }\n"
1347 "function foo() { bar(); }",
1348 "asm: line 1: left and right side of comparison must match type "
1349 "and be signed, unsigned, float, or double\n");
1350 }
1351
1352 TEST(FunctionRepeated) {
1353 CHECK_FUNC_ERROR(
1354 "function foo() { return 0; }\n"
1355 "function foo() { return 0; }",
1356 "asm: line 2: function repeated in module\n");
1357 }
1358
1359 TEST(Float64ToInt32) {
1360 CHECK_FUNC_TYPES_BEGIN(
1361 "function bar() { var x = 1; var y = 0.0; x = ~~y; }\n"
1362 "function foo() { bar(); }") {
1363 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1364 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1365 CHECK_VAR(x, Bounds(cache.kAsmInt));
1366 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1367 }
1368 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
1369 CHECK_VAR(y, Bounds(cache.kAsmDouble));
1370 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1371 }
1372 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1373 CHECK_VAR(x, Bounds(cache.kAsmInt));
1374 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1375 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1376 CHECK_VAR(y, Bounds(cache.kAsmDouble));
1377 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
1378 }
1379 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
1380 }
1381 }
1382 }
1383 CHECK_SKIP();
1384 }
1385 CHECK_FUNC_TYPES_END
1386 }
1387
1388 TEST(Load1) {
1389 CHECK_FUNC_TYPES_BEGIN(
1390 "function bar() { var x = 1; var y = i8[x>>0]|0; }\n"
1391 "function foo() { bar(); }") {
1392 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1393 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1394 CHECK_VAR(x, Bounds(cache.kAsmInt));
1395 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1396 }
1397 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1398 CHECK_VAR(y, Bounds(cache.kAsmInt));
1399 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1400 CHECK_EXPR(Property, Bounds(cache.kAsmInt)) {
1401 CHECK_VAR(i8, Bounds(cache.kInt8Array));
1402 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
1403 CHECK_VAR(x, Bounds(cache.kAsmInt));
1404 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1405 }
1406 }
1407 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1408 }
1409 }
1410 }
1411 CHECK_SKIP();
1412 }
1413 CHECK_FUNC_TYPES_END
1414 }
1415
1416 TEST(LoadDouble) {
1417 CHECK_FUNC_TYPES_BEGIN(
1418 "function bar() { var x = 1; var y = 0.0; y = +f64[x>>3]; }\n"
1419 "function foo() { bar(); }") {
1420 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1421 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1422 CHECK_VAR(x, Bounds(cache.kAsmInt));
1423 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1424 }
1425 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
1426 CHECK_VAR(y, Bounds(cache.kAsmDouble));
1427 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1428 }
1429 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
1430 CHECK_VAR(y, Bounds(cache.kAsmDouble));
1431 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
1432 CHECK_EXPR(Property, Bounds(cache.kAsmDouble)) {
1433 CHECK_VAR(f64, Bounds(cache.kFloat64Array));
1434 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
1435 CHECK_VAR(x, Bounds(cache.kAsmInt));
1436 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1437 }
1438 }
1439 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1440 }
1441 }
1442 }
1443 CHECK_SKIP();
1444 }
1445 CHECK_FUNC_TYPES_END
1446 }
1447
1448 TEST(Store1) {
1449 CHECK_FUNC_TYPES_BEGIN(
1450 "function bar() { var x = 1; i8[x>>0] = 0; }\n"
1451 "function foo() { bar(); }") {
1452 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1453 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1454 CHECK_VAR(x, Bounds(cache.kAsmInt));
1455 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1456 }
1457 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1458 CHECK_EXPR(Property, Bounds::Unbounded()) {
1459 CHECK_VAR(i8, Bounds(cache.kInt8Array));
1460 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
1461 CHECK_VAR(x, Bounds(cache.kAsmInt));
1462 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1463 }
1464 }
1465 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1466 }
1467 }
1468 CHECK_SKIP();
1469 }
1470 CHECK_FUNC_TYPES_END
1471 }
1472
1473 TEST(StoreFloat) {
1474 CHECK_FUNC_TYPES_BEGIN(
1475 "function bar() { var x = fround(1.0); "
1476 "f32[0] = fround(x + fround(1.0)); }\n"
1477 "function foo() { bar(); }") {
1478 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1479 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
1480 CHECK_VAR(x, Bounds(cache.kAsmFloat));
1481 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
1482 CHECK_VAR(fround, FUNC_N2F_TYPE);
1483 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1484 }
1485 }
1486 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
1487 CHECK_EXPR(Property, Bounds::Unbounded()) {
1488 CHECK_VAR(f32, Bounds(cache.kFloat32Array));
1489 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1490 }
1491 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
1492 CHECK_VAR(fround, FUNC_N2F_TYPE);
1493 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmFloat)) {
1494 CHECK_VAR(x, Bounds(cache.kAsmFloat));
1495 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
1496 CHECK_VAR(fround, FUNC_N2F_TYPE);
1497 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1498 }
1499 }
1500 }
1501 }
1502 }
1503 CHECK_SKIP();
1504 }
1505 CHECK_FUNC_TYPES_END
1506 }
1507
1508 TEST(StoreIntish) {
1509 CHECK_FUNC_TYPES_BEGIN(
1510 "function bar() { var x = 1; var y = 1; i32[0] = x + y; }\n"
1511 "function foo() { bar(); }") {
1512 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1513 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1514 CHECK_VAR(x, Bounds(cache.kAsmInt));
1515 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1516 }
1517 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1518 CHECK_VAR(y, Bounds(cache.kAsmInt));
1519 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1520 }
1521 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1522 CHECK_EXPR(Property, Bounds::Unbounded()) {
1523 CHECK_VAR(i32, Bounds(cache.kInt32Array));
1524 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1525 }
1526 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
1527 CHECK_VAR(x, Bounds(cache.kAsmInt));
1528 CHECK_VAR(y, Bounds(cache.kAsmInt));
1529 }
1530 }
1531 }
1532 CHECK_SKIP();
1533 }
1534 CHECK_FUNC_TYPES_END
1535 }
1536
1537 TEST(StoreFloatish) {
1538 CHECK_FUNC_TYPES_BEGIN(
1539 "function bar() { "
1540 "var x = fround(1.0); "
1541 "var y = fround(1.0); f32[0] = x + y; }\n"
1542 "function foo() { bar(); }") {
1543 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1544 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
1545 CHECK_VAR(x, Bounds(cache.kAsmFloat));
1546 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
1547 CHECK_VAR(fround, FUNC_N2F_TYPE);
1548 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1549 }
1550 }
1551 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
1552 CHECK_VAR(y, Bounds(cache.kAsmFloat));
1553 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
1554 CHECK_VAR(fround, FUNC_N2F_TYPE);
1555 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1556 }
1557 }
1558 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
1559 CHECK_EXPR(Property, Bounds::Unbounded()) {
1560 CHECK_VAR(f32, Bounds(cache.kFloat32Array));
1561 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1562 }
1563 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmFloat)) {
1564 CHECK_VAR(x, Bounds(cache.kAsmFloat));
1565 CHECK_VAR(y, Bounds(cache.kAsmFloat));
1566 }
1567 }
1568 }
1569 CHECK_SKIP();
1570 }
1571 CHECK_FUNC_TYPES_END
1572 }
1573
1574 TEST(Load1Constant) {
1575 CHECK_FUNC_TYPES_BEGIN(
1576 "function bar() { var x = 1; var y = i8[5]|0; }\n"
1577 "function foo() { bar(); }") {
1578 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1579 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1580 CHECK_VAR(x, Bounds(cache.kAsmInt));
1581 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1582 }
1583 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1584 CHECK_VAR(y, Bounds(cache.kAsmInt));
1585 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1586 CHECK_EXPR(Property, Bounds(cache.kAsmInt)) {
1587 CHECK_VAR(i8, Bounds(cache.kInt8Array));
1588 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1589 }
1590 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1591 }
1592 }
1593 }
1594 CHECK_SKIP();
1595 }
1596 CHECK_FUNC_TYPES_END
1597 }
1598
1599 TEST(FunctionTables) {
1600 CHECK_FUNC_TYPES_BEGIN(
1601 "function func1(x) { x = x | 0; return (x * 5) | 0; }\n"
1602 "function func2(x) { x = x | 0; return (x * 25) | 0; }\n"
1603 "var table1 = [func1, func2];\n"
1604 "function bar(x, y) { x = x | 0; y = y | 0;\n"
1605 " return table1[x & 1](y)|0; }\n"
1606 "function foo() { bar(1, 2); }") {
1607 CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) {
1608 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1609 CHECK_VAR(x, Bounds(cache.kAsmInt));
1610 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1611 CHECK_VAR(x, Bounds(cache.kAsmInt));
1612 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1613 }
1614 }
1615 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1616 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
1617 CHECK_VAR(x, Bounds(cache.kAsmInt));
1618 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1619 }
1620 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1621 }
1622 }
1623 CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) {
1624 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1625 CHECK_VAR(x, Bounds(cache.kAsmInt));
1626 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1627 CHECK_VAR(x, Bounds(cache.kAsmInt));
1628 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1629 }
1630 }
1631 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1632 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
1633 CHECK_VAR(x, Bounds(cache.kAsmInt));
1634 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1635 }
1636 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1637 }
1638 }
1639 CHECK_EXPR(FunctionLiteral, FUNC_II2I_TYPE) {
1640 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1641 CHECK_VAR(x, Bounds(cache.kAsmInt));
1642 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1643 CHECK_VAR(x, Bounds(cache.kAsmInt));
1644 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1645 }
1646 }
1647 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1648 CHECK_VAR(y, Bounds(cache.kAsmInt));
1649 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1650 CHECK_VAR(y, Bounds(cache.kAsmInt));
1651 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1652 }
1653 }
1654 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1655 CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
1656 CHECK_EXPR(Property, FUNC_I2I_TYPE) {
1657 CHECK_VAR(table1, FUNC_I2I_ARRAY_TYPE);
1658 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1659 // TODO(bradnelson): revert this
1660 // CHECK_VAR(x, Bounds(cache.kAsmSigned));
1661 CHECK_VAR(x, Bounds(cache.kAsmInt));
1662 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1663 }
1664 }
1665 CHECK_VAR(y, Bounds(cache.kAsmInt));
1666 }
1667 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1668 }
1669 }
1670 CHECK_SKIP();
1671 }
1672 CHECK_FUNC_TYPES_END_1();
1673 CHECK_EXPR(Assignment, FUNC_I2I_ARRAY_TYPE) {
1674 CHECK_VAR(table1, FUNC_I2I_ARRAY_TYPE);
1675 CHECK_EXPR(ArrayLiteral, FUNC_I2I_ARRAY_TYPE) {
1676 CHECK_VAR(func1, FUNC_I2I_TYPE);
1677 CHECK_VAR(func2, FUNC_I2I_TYPE);
1678 }
1679 }
1680 CHECK_FUNC_TYPES_END_2();
1681 }
1682
1683 TEST(BadFunctionTable) {
1684 CHECK_FUNC_ERROR(
1685 "function func1(x) { x = x | 0; return (x * 5) | 0; }\n"
1686 "var table1 = [func1, 1];\n"
1687 "function bar(x, y) { x = x | 0; y = y | 0;\n"
1688 " return table1[x & 1](y)|0; }\n"
1689 "function foo() { bar(1, 2); }",
1690 "asm: line 2: array component expected to be a function\n");
1691 }
1692
1693 TEST(MissingParameterTypes) {
1694 CHECK_FUNC_ERROR(
1695 "function bar(x) { var y = 1; }\n"
1696 "function foo() { bar(2); }",
1697 "asm: line 1: missing parameter type annotations\n");
1698 }
1699
1700 TEST(InvalidTypeAnnotationBinaryOpDiv) {
1701 CHECK_FUNC_ERROR(
1702 "function bar(x) { x = x / 4; }\n"
1703 "function foo() { bar(2); }",
1704 "asm: line 1: invalid type annotation on binary op\n");
1705 }
1706
1707 TEST(InvalidTypeAnnotationBinaryOpMul) {
1708 CHECK_FUNC_ERROR(
1709 "function bar(x) { x = x * 4.0; }\n"
1710 "function foo() { bar(2); }",
1711 "asm: line 1: invalid type annotation on binary op\n");
1712 }
1713
1714 TEST(InvalidArgumentCount) {
1715 CHECK_FUNC_ERROR(
1716 "function bar(x) { return fround(4, 5); }\n"
1717 "function foo() { bar(); }",
1718 "asm: line 1: invalid argument count calling function\n");
1719 }
1720
1721 TEST(InvalidTypeAnnotationArity) {
1722 CHECK_FUNC_ERROR(
1723 "function bar(x) { x = max(x); }\n"
1724 "function foo() { bar(3); }",
1725 "asm: line 1: only fround allowed on expression annotations\n");
1726 }
1727
1728 TEST(InvalidTypeAnnotationOnlyFround) {
1729 CHECK_FUNC_ERROR(
1730 "function bar(x) { x = sin(x); }\n"
1731 "function foo() { bar(3); }",
1732 "asm: line 1: only fround allowed on expression annotations\n");
1733 }
1734
1735 TEST(InvalidTypeAnnotation) {
1736 CHECK_FUNC_ERROR(
1737 "function bar(x) { x = (x+x)(x); }\n"
1738 "function foo() { bar(3); }",
1739 "asm: line 1: invalid type annotation\n");
1740 }
1741
1742 TEST(WithStatement) {
1743 CHECK_FUNC_ERROR(
1744 "function bar() { var x = 0; with (x) { x = x + 1; } }\n"
1745 "function foo() { bar(); }",
1746 "asm: line 1: bad with statement\n");
1747 }
1748
1749 TEST(NestedFunction) {
1750 CHECK_FUNC_ERROR(
1751 "function bar() { function x() { return 1; } }\n"
1752 "function foo() { bar(); }",
1753 "asm: line 1: function declared inside another\n");
1754 }
1755
1756 TEST(UnboundVariable) {
1757 CHECK_FUNC_ERROR(
1758 "function bar() { var x = y; }\n"
1759 "function foo() { bar(); }",
1760 "asm: line 1: unbound variable\n");
1761 }
1762
1763 TEST(EqStrict) {
1764 CHECK_FUNC_ERROR(
1765 "function bar() { return (0 === 0)|0; }\n"
1766 "function foo() { bar(); }",
1767 "asm: line 1: illegal comparison operator\n");
1768 }
1769
1770 TEST(NeStrict) {
1771 CHECK_FUNC_ERROR(
1772 "function bar() { return (0 !== 0)|0; }\n"
1773 "function foo() { bar(); }",
1774 "asm: line 1: illegal comparison operator\n");
1775 }
1776
1777 TEST(InstanceOf) {
1778 CHECK_FUNC_ERROR(
1779 "function bar() { return (0 instanceof 0)|0; }\n"
1780 "function foo() { bar(); }",
1781 "asm: line 1: illegal comparison operator\n");
1782 }
1783
1784 TEST(InOperator) {
1785 CHECK_FUNC_ERROR(
1786 "function bar() { return (0 in 0)|0; }\n"
1787 "function foo() { bar(); }",
1788 "asm: line 1: illegal comparison operator\n");
1789 }
1790
1791 TEST(LogicalAndOperator) {
1792 CHECK_FUNC_ERROR(
1793 "function bar() { return (0 && 0)|0; }\n"
1794 "function foo() { bar(); }",
1795 "asm: line 1: illegal logical operator\n");
1796 }
1797
1798 TEST(LogicalOrOperator) {
1799 CHECK_FUNC_ERROR(
1800 "function bar() { return (0 || 0)|0; }\n"
1801 "function foo() { bar(); }",
1802 "asm: line 1: illegal logical operator\n");
1803 }
1804
1805 TEST(BitOrDouble) {
1806 CHECK_FUNC_ERROR(
1807 "function bar() { var x = 1.0; return x | 0; }\n"
1808 "function foo() { bar(); }",
1809 "asm: line 1: intish required\n");
1810 }
1811
1812 TEST(BadLiteral) {
1813 CHECK_FUNC_ERROR(
1814 "function bar() { return true | 0; }\n"
1815 "function foo() { bar(); }",
1816 "asm: line 1: illegal literal\n");
1817 }
1818
1819 TEST(MismatchedReturnTypeLiteral) {
1820 CHECK_FUNC_ERROR(
1821 "function bar() { if(1) { return 1; } return 1.0; }\n"
1822 "function foo() { bar(); }",
1823 "asm: line 1: return type does not match function signature\n");
1824 }
1825
1826 TEST(MismatchedReturnTypeExpression) {
1827 CHECK_FUNC_ERROR(
1828 "function bar() {\n"
1829 " var x = 1; var y = 1.0; if(1) { return x; } return +y; }\n"
1830 "function foo() { bar(); }",
1831 "asm: line 2: return type does not match function signature\n");
1832 }
1833
1834 TEST(AssignToFloatishToF64) {
1835 CHECK_FUNC_ERROR(
1836 "function bar() { var v = fround(1.0); f64[0] = v + fround(1.0); }\n"
1837 "function foo() { bar(); }",
1838 "asm: line 1: floatish assignment to double array\n");
1839 }
1840
1841 TEST(ForeignFunction) {
1842 CHECK_FUNC_TYPES_BEGIN(
1843 "var baz = foreign.baz;\n"
1844 "function bar() { return baz(1, 2)|0; }\n"
1845 "function foo() { bar(); }") {
1846 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
1847 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1848 CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
1849 CHECK_VAR(baz, FUNC_FOREIGN_TYPE);
1850 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1851 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1852 }
1853 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1854 }
1855 }
1856 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1857 CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
1858 CHECK_VAR(bar, FUNC_I_TYPE);
1859 }
1860 }
1861 }
1862 CHECK_FUNC_TYPES_END_1()
1863 CHECK_EXPR(Assignment, Bounds(FUNC_FOREIGN_TYPE)) {
1864 CHECK_VAR(baz, Bounds(FUNC_FOREIGN_TYPE));
1865 CHECK_EXPR(Property, Bounds(FUNC_FOREIGN_TYPE)) {
1866 CHECK_VAR(foreign, Bounds::Unbounded());
1867 CHECK_EXPR(Literal, Bounds::Unbounded());
1868 }
1869 }
1870 CHECK_FUNC_TYPES_END_2()
1871 }
1872
1873 TEST(ByteArray) {
1874 // Forbidden by asm.js spec, present in embenchen.
1875 CHECK_FUNC_TYPES_BEGIN(
1876 "function bar() { var x = 0; i8[x] = 2; }\n"
1877 "function foo() { bar(); }") {
1878 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1879 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1880 CHECK_VAR(x, Bounds(cache.kAsmInt));
1881 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1882 }
1883 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1884 CHECK_EXPR(Property, Bounds::Unbounded()) {
1885 CHECK_VAR(i8, Bounds(cache.kInt8Array));
1886 CHECK_VAR(x, Bounds(cache.kAsmUnsigned));
1887 }
1888 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1889 }
1890 }
1891 CHECK_SKIP();
1892 }
1893 CHECK_FUNC_TYPES_END
1894 }
1895
1896 TEST(BadExports) {
1897 HARNESS_PREAMBLE()
1898 "function foo() {};\n"
1899 "return {foo: foo, bar: 1};"
1900 "}\n";
1901
1902 v8::V8::Initialize();
1903 HandleAndZoneScope handles;
1904 Zone* zone = handles.main_zone();
1905 ZoneVector<ExpressionTypeEntry> types(zone);
1906 CHECK_EQ("asm: line 2: non-function in function table\n",
1907 Validate(zone, test_function, &types));
1908 }
1909
1910 TEST(NestedHeapAssignment) {
1911 CHECK_FUNC_ERROR(
1912 "function bar() { var x = 0; i16[x = 1] = 2; }\n"
1913 "function foo() { bar(); }",
1914 "asm: line 1: expected >> in heap access\n");
1915 }
1916
1917 TEST(BadOperatorHeapAssignment) {
1918 CHECK_FUNC_ERROR(
1919 "function bar() { var x = 0; i16[x & 1] = 2; }\n"
1920 "function foo() { bar(); }",
1921 "asm: line 1: expected >> in heap access\n");
1922 }
1923
1924 TEST(BadArrayAssignment) {
1925 CHECK_FUNC_ERROR(
1926 "function bar() { i8[0] = 0.0; }\n"
1927 "function foo() { bar(); }",
1928 "asm: line 1: illegal type in assignment\n");
1929 }
1930
1931 TEST(BadStandardFunctionCallOutside) {
1932 CHECK_FUNC_ERROR(
1933 "var s0 = sin(0);\n"
1934 "function bar() { }\n"
1935 "function foo() { bar(); }",
1936 "asm: line 1: illegal variable reference in module body\n");
1937 }
1938
1939 TEST(BadFunctionCallOutside) {
1940 CHECK_FUNC_ERROR(
1941 "function bar() { return 0.0; }\n"
1942 "var s0 = bar(0);\n"
1943 "function foo() { bar(); }",
1944 "asm: line 2: illegal variable reference in module body\n");
1945 }
1946
1947 TEST(UnaryPlusOnIntForbidden) {
1948 CHECK_FUNC_ERROR(
1949 "function bar() { var x = 1; return +x; }\n"
1950 "function foo() { bar(); }",
1951 "asm: line 1: "
1952 "unary + only allowed on signed, unsigned, float?, or double?\n");
1953 }
1954
1955 TEST(MultiplyNon1ConvertForbidden) {
1956 CHECK_FUNC_ERROR(
1957 "function bar() { var x = 0.0; return x * 2.0; }\n"
1958 "function foo() { bar(); }",
1959 "asm: line 1: invalid type annotation on binary op\n");
1960 }
1961
1962 TEST(NestedVariableAssignment) {
1963 CHECK_FUNC_TYPES_BEGIN(
1964 "function bar() { var x = 0; x = x = 4; }\n"
1965 "function foo() { bar(); }") {
1966 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1967 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1968 CHECK_VAR(x, Bounds(cache.kAsmInt));
1969 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1970 }
1971 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1972 CHECK_VAR(x, Bounds(cache.kAsmInt));
1973 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1974 CHECK_VAR(x, Bounds(cache.kAsmInt));
1975 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1976 }
1977 }
1978 }
1979 CHECK_SKIP();
1980 }
1981 CHECK_FUNC_TYPES_END
1982 }
1983
1984 TEST(NestedAssignmentInHeap) {
1985 CHECK_FUNC_TYPES_BEGIN(
1986 "function bar() { var x = 0; i8[(x = 1) >> 0] = 2; }\n"
1987 "function foo() { bar(); }") {
1988 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1989 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1990 CHECK_VAR(x, Bounds(cache.kAsmInt));
1991 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1992 }
1993 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1994 CHECK_EXPR(Property, Bounds::Unbounded()) {
1995 CHECK_VAR(i8, Bounds(cache.kInt8Array));
1996 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
1997 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1998 CHECK_VAR(x, Bounds(cache.kAsmInt));
1999 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2000 }
2001 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2002 }
2003 }
2004 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2005 }
2006 }
2007 CHECK_SKIP();
2008 }
2009 CHECK_FUNC_TYPES_END
2010 }
2011
2012 TEST(NegativeDouble) {
2013 CHECK_FUNC_TYPES_BEGIN(
2014 "function bar() { var x = -123.2; }\n"
2015 "function foo() { bar(); }") {
2016 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
2017 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
2018 CHECK_VAR(x, Bounds(cache.kAsmDouble));
2019 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2020 }
2021 }
2022 CHECK_SKIP();
2023 }
2024 CHECK_FUNC_TYPES_END
2025 }
2026
2027 TEST(NegativeInteger) {
2028 CHECK_FUNC_TYPES_BEGIN(
2029 "function bar() { var x = -123; }\n"
2030 "function foo() { bar(); }") {
2031 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
2032 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
2033 CHECK_VAR(x, Bounds(cache.kAsmInt));
2034 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
2035 }
2036 }
2037 CHECK_SKIP();
2038 }
2039 CHECK_FUNC_TYPES_END
2040 }
2041
2042 TEST(AbsFunction) {
2043 CHECK_FUNC_TYPES_BEGIN(
2044 "function bar() { var x = -123.0; x = abs(x); }\n"
2045 "function foo() { bar(); }") {
2046 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
2047 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
2048 CHECK_VAR(x, Bounds(cache.kAsmDouble));
2049 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2050 }
2051 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
2052 CHECK_VAR(x, Bounds(cache.kAsmDouble));
2053 CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
2054 CHECK_VAR(abs, FUNC_N2N_TYPE);
2055 CHECK_VAR(x, Bounds(cache.kAsmDouble));
2056 }
2057 }
2058 }
2059 CHECK_SKIP();
2060 }
2061 CHECK_FUNC_TYPES_END
2062 }
2063
2064 TEST(CeilFloat) {
2065 CHECK_FUNC_TYPES_BEGIN(
2066 "function bar() { var x = fround(3.1); x = ceil(x); }\n"
2067 "function foo() { bar(); }") {
2068 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
2069 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
2070 CHECK_VAR(x, Bounds(cache.kAsmFloat));
2071 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
2072 CHECK_VAR(fround, FUNC_N2F_TYPE);
2073 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2074 }
2075 }
2076 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
2077 CHECK_VAR(x, Bounds(cache.kAsmFloat));
2078 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
2079 CHECK_VAR(ceil, FUNC_N2N_TYPE);
2080 CHECK_VAR(x, Bounds(cache.kAsmFloat));
2081 }
2082 }
2083 }
2084 CHECK_SKIP();
2085 }
2086 CHECK_FUNC_TYPES_END
2087 }
2088
2089 TEST(FloatReturnAsDouble) {
2090 CHECK_FUNC_TYPES_BEGIN(
2091 "function bar() { var x = fround(3.1); return +fround(x); }\n"
2092 "function foo() { bar(); }") {
2093 CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) {
2094 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
2095 CHECK_VAR(x, Bounds(cache.kAsmFloat));
2096 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
2097 CHECK_VAR(fround, FUNC_N2F_TYPE);
2098 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2099 }
2100 }
2101 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
2102 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
2103 CHECK_VAR(fround, FUNC_N2F_TYPE);
2104 CHECK_VAR(x, Bounds(cache.kAsmFloat));
2105 }
2106 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2107 }
2108 }
2109 CHECK_SKIP();
2110 }
2111 CHECK_FUNC_TYPES_END
2112 }
2113
2114 TEST(TypeConsistency) {
2115 v8::V8::Initialize();
2116 TypeCache cache;
2117 // Check the consistency of each of the main Asm.js types.
2118 CHECK(cache.kAsmFixnum->Is(cache.kAsmFixnum));
2119 CHECK(cache.kAsmFixnum->Is(cache.kAsmSigned));
2120 CHECK(cache.kAsmFixnum->Is(cache.kAsmUnsigned));
2121 CHECK(cache.kAsmFixnum->Is(cache.kAsmInt));
2122 CHECK(!cache.kAsmFixnum->Is(cache.kAsmFloat));
2123 CHECK(!cache.kAsmFixnum->Is(cache.kAsmDouble));
2124
2125 CHECK(cache.kAsmSigned->Is(cache.kAsmSigned));
2126 CHECK(cache.kAsmSigned->Is(cache.kAsmInt));
2127 CHECK(!cache.kAsmSigned->Is(cache.kAsmFixnum));
2128 CHECK(!cache.kAsmSigned->Is(cache.kAsmUnsigned));
2129 CHECK(!cache.kAsmSigned->Is(cache.kAsmFloat));
2130 CHECK(!cache.kAsmSigned->Is(cache.kAsmDouble));
2131
2132 CHECK(cache.kAsmUnsigned->Is(cache.kAsmUnsigned));
2133 CHECK(cache.kAsmUnsigned->Is(cache.kAsmInt));
2134 CHECK(!cache.kAsmUnsigned->Is(cache.kAsmSigned));
2135 CHECK(!cache.kAsmUnsigned->Is(cache.kAsmFixnum));
2136 CHECK(!cache.kAsmUnsigned->Is(cache.kAsmFloat));
2137 CHECK(!cache.kAsmUnsigned->Is(cache.kAsmDouble));
2138
2139 CHECK(cache.kAsmInt->Is(cache.kAsmInt));
2140 CHECK(!cache.kAsmInt->Is(cache.kAsmUnsigned));
2141 CHECK(!cache.kAsmInt->Is(cache.kAsmSigned));
2142 CHECK(!cache.kAsmInt->Is(cache.kAsmFixnum));
2143 CHECK(!cache.kAsmInt->Is(cache.kAsmFloat));
2144 CHECK(!cache.kAsmInt->Is(cache.kAsmDouble));
2145
2146 CHECK(cache.kAsmFloat->Is(cache.kAsmFloat));
2147 CHECK(!cache.kAsmFloat->Is(cache.kAsmInt));
2148 CHECK(!cache.kAsmFloat->Is(cache.kAsmUnsigned));
2149 CHECK(!cache.kAsmFloat->Is(cache.kAsmSigned));
2150 CHECK(!cache.kAsmFloat->Is(cache.kAsmFixnum));
2151 CHECK(!cache.kAsmFloat->Is(cache.kAsmDouble));
2152
2153 CHECK(cache.kAsmDouble->Is(cache.kAsmDouble));
2154 CHECK(!cache.kAsmDouble->Is(cache.kAsmInt));
2155 CHECK(!cache.kAsmDouble->Is(cache.kAsmUnsigned));
2156 CHECK(!cache.kAsmDouble->Is(cache.kAsmSigned));
2157 CHECK(!cache.kAsmDouble->Is(cache.kAsmFixnum));
2158 CHECK(!cache.kAsmDouble->Is(cache.kAsmFloat));
2159 }
2160
2161 TEST(SwitchTest) {
2162 CHECK_FUNC_TYPES_BEGIN(
2163 "function switcher(x) {\n"
2164 " x = x|0;\n"
2165 " switch (x|0) {\n"
2166 " case 1: return 23;\n"
2167 " case 2: return 43;\n"
2168 " default: return 66;\n"
2169 " }\n"
2170 " return 0;\n"
2171 "}\n"
2172 "function foo() { switcher(1); }") {
2173 CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) {
2174 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
2175 CHECK_VAR(x, Bounds(cache.kAsmInt));
2176 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
2177 CHECK_VAR(x, Bounds(cache.kAsmInt));
2178 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2179 }
2180 }
2181 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
2182 CHECK_VAR(.switch_tag, Bounds(cache.kAsmInt));
2183 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
2184 CHECK_VAR(x, Bounds(cache.kAsmInt));
2185 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2186 }
2187 }
2188 CHECK_EXPR(Literal, Bounds(Type::Undefined()));
2189 CHECK_VAR(.switch_tag, Bounds(cache.kAsmSigned));
2190 // case 1: return 23;
2191 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2192 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
2193 // case 2: return 43;
2194 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2195 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
2196 // default: return 66;
2197 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
2198 // return 0;
2199 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
2200 }
2201 CHECK_SKIP();
2202 }
2203 CHECK_FUNC_TYPES_END
2204 }
2205
2206 TEST(BadSwitchRange) {
2207 CHECK_FUNC_ERROR(
2208 "function bar() { switch (1) { case -1: case 0x7fffffff: } }\n"
2209 "function foo() { bar(); }",
2210 "asm: line 1: case range too large\n");
2211 }
2212
2213 TEST(DuplicateSwitchCase) {
2214 CHECK_FUNC_ERROR(
2215 "function bar() { switch (1) { case 0: case 0: } }\n"
2216 "function foo() { bar(); }",
2217 "asm: line 1: duplicate case value\n");
2218 }
2219
2220 TEST(BadSwitchOrder) {
2221 CHECK_FUNC_ERROR(
2222 "function bar() { switch (1) { default: case 0: } }\n"
2223 "function foo() { bar(); }",
2224 "asm: line 1: default case out of order\n");
2225 }
2226
2227 TEST(BadForeignCall) {
2228 const char test_function[] =
2229 "function TestModule(stdlib, foreign, buffer) {\n"
2230 " \"use asm\";\n"
2231 " var ffunc = foreign.foo;\n"
2232 " function test1() { var x = 0; ffunc(x); }\n"
2233 " return { testFunc1: test1 };\n"
2234 "}\n";
2235 v8::V8::Initialize();
2236 HandleAndZoneScope handles;
2237 Zone* zone = handles.main_zone();
2238 ZoneVector<ExpressionTypeEntry> types(zone);
2239 CHECK_EQ(
2240 "asm: line 4: foreign call argument expected to be int, double, or "
2241 "fixnum\n",
2242 Validate(zone, test_function, &types));
2243 }
2244
2245 TEST(BadImports) {
2246 const char test_function[] =
2247 "function TestModule(stdlib, foreign, buffer) {\n"
2248 " \"use asm\";\n"
2249 " var fint = (foreign.bar | 0) | 0;\n"
2250 " function test1() {}\n"
2251 " return { testFunc1: test1 };\n"
2252 "}\n";
2253 v8::V8::Initialize();
2254 HandleAndZoneScope handles;
2255 Zone* zone = handles.main_zone();
2256 ZoneVector<ExpressionTypeEntry> types(zone);
2257 CHECK_EQ("asm: line 3: illegal computation inside module body\n",
2258 Validate(zone, test_function, &types));
2259 }
2260
2261 TEST(BadVariableReference) {
2262 const char test_function[] =
2263 "function TestModule(stdlib, foreign, buffer) {\n"
2264 " \"use asm\";\n"
2265 " var x = 0;\n"
2266 " var y = x;\n"
2267 " function test1() {}\n"
2268 " return { testFunc1: test1 };\n"
2269 "}\n";
2270 v8::V8::Initialize();
2271 HandleAndZoneScope handles;
2272 Zone* zone = handles.main_zone();
2273 ZoneVector<ExpressionTypeEntry> types(zone);
2274 CHECK_EQ("asm: line 4: illegal variable reference in module body\n",
2275 Validate(zone, test_function, &types));
2276 }
2277
2278 TEST(BadForeignVariableReferenceValueOr) {
2279 const char test_function[] =
2280 "function TestModule(stdlib, foreign, buffer) {\n"
2281 " \"use asm\";\n"
2282 " var fint = foreign.bar | 1;\n"
2283 "}\n";
2284 v8::V8::Initialize();
2285 HandleAndZoneScope handles;
2286 Zone* zone = handles.main_zone();
2287 ZoneVector<ExpressionTypeEntry> types(zone);
2288 CHECK_EQ("asm: line 3: illegal integer annotation value\n",
2289 Validate(zone, test_function, &types));
2290 }
2291
2292 TEST(BadForeignVariableReferenceValueOrDot) {
2293 const char test_function[] =
2294 "function TestModule(stdlib, foreign, buffer) {\n"
2295 " \"use asm\";\n"
2296 " var fint = foreign.bar | 1.0;\n"
2297 "}\n";
2298 v8::V8::Initialize();
2299 HandleAndZoneScope handles;
2300 Zone* zone = handles.main_zone();
2301 ZoneVector<ExpressionTypeEntry> types(zone);
2302 CHECK_EQ("asm: line 3: illegal integer annotation value\n",
2303 Validate(zone, test_function, &types));
2304 }
2305
2306 TEST(BadForeignVariableReferenceValueMul) {
2307 const char test_function[] =
2308 "function TestModule(stdlib, foreign, buffer) {\n"
2309 " \"use asm\";\n"
2310 " var fint = foreign.bar * 2.0;\n"
2311 "}\n";
2312 v8::V8::Initialize();
2313 HandleAndZoneScope handles;
2314 Zone* zone = handles.main_zone();
2315 ZoneVector<ExpressionTypeEntry> types(zone);
2316 CHECK_EQ("asm: line 3: illegal double annotation value\n",
2317 Validate(zone, test_function, &types));
2318 }
2319
2320 TEST(BadForeignVariableReferenceValueMulNoDot) {
2321 const char test_function[] =
2322 "function TestModule(stdlib, foreign, buffer) {\n"
2323 " \"use asm\";\n"
2324 " var fint = foreign.bar * 1;\n"
2325 "}\n";
2326 v8::V8::Initialize();
2327 HandleAndZoneScope handles;
2328 Zone* zone = handles.main_zone();
2329 ZoneVector<ExpressionTypeEntry> types(zone);
2330 CHECK_EQ("asm: line 3: ill-typed arithmetic operation\n",
2331 Validate(zone, test_function, &types));
2332 }
2333
2334 TEST(Imports) {
2335 const char test_function[] =
2336 "function TestModule(stdlib, foreign, buffer) {\n"
2337 " \"use asm\";\n"
2338 " var ffunc = foreign.foo;\n"
2339 " var fint = foreign.bar | 0;\n"
2340 " var fdouble = +foreign.baz;\n"
2341 " function test1() { return ffunc(fint|0, fdouble) | 0; }\n"
2342 " function test2() { return +ffunc(fdouble, fint|0); }\n"
2343 " return { testFunc1: test1, testFunc2: test2 };\n"
2344 "}\n";
2345
2346 v8::V8::Initialize();
2347 HandleAndZoneScope handles;
2348 Zone* zone = handles.main_zone();
2349 ZoneVector<ExpressionTypeEntry> types(zone);
2350 CHECK_EQ("", Validate(zone, test_function, &types));
2351 TypeCache cache;
2352
2353 CHECK_TYPES_BEGIN {
2354 // Module.
2355 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
2356 // function test1
2357 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
2358 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
2359 CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
2360 CHECK_VAR(ffunc, FUNC_FOREIGN_TYPE);
2361 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
2362 CHECK_VAR(fint, Bounds(cache.kAsmInt));
2363 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2364 }
2365 CHECK_VAR(fdouble, Bounds(cache.kAsmDouble));
2366 }
2367 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2368 }
2369 }
2370 // function test2
2371 CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) {
2372 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
2373 CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
2374 CHECK_VAR(ffunc, FUNC_FOREIGN_TYPE);
2375 CHECK_VAR(fdouble, Bounds(cache.kAsmDouble));
2376 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
2377 CHECK_VAR(fint, Bounds(cache.kAsmInt));
2378 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2379 }
2380 }
2381 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2382 }
2383 }
2384 // "use asm";
2385 CHECK_EXPR(Literal, Bounds(Type::String()));
2386 // var func = foreign.foo;
2387 CHECK_EXPR(Assignment, Bounds(FUNC_FOREIGN_TYPE)) {
2388 CHECK_VAR(ffunc, Bounds(FUNC_FOREIGN_TYPE));
2389 CHECK_EXPR(Property, Bounds(FUNC_FOREIGN_TYPE)) {
2390 CHECK_VAR(foreign, Bounds::Unbounded());
2391 CHECK_EXPR(Literal, Bounds::Unbounded());
2392 }
2393 }
2394 // var fint = foreign.bar | 0;
2395 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
2396 CHECK_VAR(fint, Bounds(cache.kAsmInt));
2397 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
2398 CHECK_EXPR(Property, Bounds(Type::Number())) {
2399 CHECK_VAR(foreign, Bounds::Unbounded());
2400 CHECK_EXPR(Literal, Bounds::Unbounded());
2401 }
2402 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2403 }
2404 }
2405 // var fdouble = +foreign.baz;
2406 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
2407 CHECK_VAR(fdouble, Bounds(cache.kAsmDouble));
2408 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
2409 CHECK_EXPR(Property, Bounds(Type::Number())) {
2410 CHECK_VAR(foreign, Bounds::Unbounded());
2411 CHECK_EXPR(Literal, Bounds::Unbounded());
2412 }
2413 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2414 }
2415 }
2416 // return { testFunc1: test1, testFunc2: test2 };
2417 CHECK_EXPR(ObjectLiteral, Bounds::Unbounded()) {
2418 CHECK_VAR(test1, FUNC_I_TYPE);
2419 CHECK_VAR(test2, FUNC_D_TYPE);
2420 }
2421 }
2422 }
2423 CHECK_TYPES_END
2424 }
2425
2426 TEST(StoreFloatFromDouble) {
2427 CHECK_FUNC_TYPES_BEGIN(
2428 "function bar() { f32[0] = 0.0; }\n"
2429 "function foo() { bar(); }") {
2430 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
2431 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
2432 CHECK_EXPR(Property, Bounds::Unbounded()) {
2433 CHECK_VAR(f32, Bounds(cache.kFloat32Array));
2434 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2435 }
2436 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2437 }
2438 }
2439 CHECK_SKIP();
2440 }
2441 CHECK_FUNC_TYPES_END
2442 }
2443
2444 TEST(NegateDouble) {
2445 CHECK_FUNC_TYPES_BEGIN(
2446 "function bar() { var x = 0.0; x = -x; }\n"
2447 "function foo() { bar(); }") {
2448 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
2449 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
2450 CHECK_VAR(x, Bounds(cache.kAsmDouble));
2451 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2452 }
2453 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
2454 CHECK_VAR(x, Bounds(cache.kAsmDouble));
2455 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
2456 CHECK_VAR(x, Bounds(cache.kAsmDouble));
2457 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2458 }
2459 }
2460 }
2461 CHECK_SKIP();
2462 }
2463 CHECK_FUNC_TYPES_END
2464 }
OLDNEW
« no previous file with comments | « test/cctest/OWNERS ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698