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