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