blob: a07eecf2760644d9309eaf7034583bb1c3d4b2ac [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
1364
1365TEST(Float64ToInt32) {
1366 CHECK_FUNC_TYPES_BEGIN(
1367 "function bar() { var x = 1; var y = 0.0; x = ~~y; }\n"
1368 "function foo() { bar(); }") {
1369 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1370 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1371 CHECK_VAR(x, Bounds(cache.kAsmInt));
1372 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1373 }
1374 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
1375 CHECK_VAR(y, Bounds(cache.kAsmDouble));
1376 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1377 }
1378 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1379 CHECK_VAR(x, Bounds(cache.kAsmInt));
1380 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1381 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1382 CHECK_VAR(y, Bounds(cache.kAsmDouble));
1383 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
1384 }
1385 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
1386 }
1387 }
1388 }
1389 CHECK_SKIP();
1390 }
1391 CHECK_FUNC_TYPES_END
1392}
1393
1394
1395TEST(Load1) {
1396 CHECK_FUNC_TYPES_BEGIN(
1397 "function bar() { var x = 1; var y = i8[x>>0]|0; }\n"
1398 "function foo() { bar(); }") {
1399 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1400 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1401 CHECK_VAR(x, Bounds(cache.kAsmInt));
1402 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1403 }
1404 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1405 CHECK_VAR(y, Bounds(cache.kAsmInt));
1406 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1407 CHECK_EXPR(Property, Bounds(cache.kAsmInt)) {
1408 CHECK_VAR(i8, Bounds(cache.kInt8Array));
1409 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001410 CHECK_VAR(x, Bounds(cache.kAsmInt));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001411 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1412 }
1413 }
1414 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1415 }
1416 }
1417 }
1418 CHECK_SKIP();
1419 }
1420 CHECK_FUNC_TYPES_END
1421}
1422
1423
1424TEST(LoadDouble) {
1425 CHECK_FUNC_TYPES_BEGIN(
1426 "function bar() { var x = 1; var y = 0.0; y = +f64[x>>3]; }\n"
1427 "function foo() { bar(); }") {
1428 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1429 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1430 CHECK_VAR(x, Bounds(cache.kAsmInt));
1431 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1432 }
1433 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
1434 CHECK_VAR(y, Bounds(cache.kAsmDouble));
1435 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1436 }
1437 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
1438 CHECK_VAR(y, Bounds(cache.kAsmDouble));
1439 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
1440 CHECK_EXPR(Property, Bounds(cache.kAsmDouble)) {
1441 CHECK_VAR(f64, Bounds(cache.kFloat64Array));
1442 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1443 CHECK_VAR(x, Bounds(cache.kAsmSigned));
1444 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1445 }
1446 }
1447 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1448 }
1449 }
1450 }
1451 CHECK_SKIP();
1452 }
1453 CHECK_FUNC_TYPES_END
1454}
1455
1456
1457TEST(Store1) {
1458 CHECK_FUNC_TYPES_BEGIN(
1459 "function bar() { var x = 1; i8[x>>0] = 0; }\n"
1460 "function foo() { bar(); }") {
1461 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1462 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1463 CHECK_VAR(x, Bounds(cache.kAsmInt));
1464 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1465 }
1466 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1467 CHECK_EXPR(Property, Bounds::Unbounded()) {
1468 CHECK_VAR(i8, Bounds(cache.kInt8Array));
1469 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001470 CHECK_VAR(x, Bounds(cache.kAsmInt));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001471 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1472 }
1473 }
1474 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1475 }
1476 }
1477 CHECK_SKIP();
1478 }
1479 CHECK_FUNC_TYPES_END
1480}
1481
1482
1483TEST(StoreFloat) {
1484 CHECK_FUNC_TYPES_BEGIN(
1485 "function bar() { var x = fround(1.0); "
1486 "f32[0] = fround(x + fround(1.0)); }\n"
1487 "function foo() { bar(); }") {
1488 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1489 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
1490 CHECK_VAR(x, Bounds(cache.kAsmFloat));
1491 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
1492 CHECK_VAR(fround, FUNC_N2F_TYPE);
1493 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1494 }
1495 }
1496 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
1497 CHECK_EXPR(Property, Bounds::Unbounded()) {
1498 CHECK_VAR(f32, Bounds(cache.kFloat32Array));
1499 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1500 }
1501 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
1502 CHECK_VAR(fround, FUNC_N2F_TYPE);
1503 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmFloat)) {
1504 CHECK_VAR(x, Bounds(cache.kAsmFloat));
1505 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
1506 CHECK_VAR(fround, FUNC_N2F_TYPE);
1507 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1508 }
1509 }
1510 }
1511 }
1512 }
1513 CHECK_SKIP();
1514 }
1515 CHECK_FUNC_TYPES_END
1516}
1517
Ben Murdoch097c5b22016-05-18 11:27:45 +01001518TEST(StoreIntish) {
1519 CHECK_FUNC_TYPES_BEGIN(
1520 "function bar() { var x = 1; var y = 1; i32[0] = x + y; }\n"
1521 "function foo() { bar(); }") {
1522 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1523 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1524 CHECK_VAR(x, Bounds(cache.kAsmInt));
1525 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1526 }
1527 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1528 CHECK_VAR(y, Bounds(cache.kAsmInt));
1529 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1530 }
1531 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1532 CHECK_EXPR(Property, Bounds::Unbounded()) {
1533 CHECK_VAR(i32, Bounds(cache.kInt32Array));
1534 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1535 }
1536 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
1537 CHECK_VAR(x, Bounds(cache.kAsmInt));
1538 CHECK_VAR(y, Bounds(cache.kAsmInt));
1539 }
1540 }
1541 }
1542 CHECK_SKIP();
1543 }
1544 CHECK_FUNC_TYPES_END
1545}
1546
1547TEST(StoreFloatish) {
1548 CHECK_FUNC_TYPES_BEGIN(
1549 "function bar() { "
1550 "var x = fround(1.0); "
1551 "var y = fround(1.0); f32[0] = x + y; }\n"
1552 "function foo() { bar(); }") {
1553 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1554 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
1555 CHECK_VAR(x, Bounds(cache.kAsmFloat));
1556 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
1557 CHECK_VAR(fround, FUNC_N2F_TYPE);
1558 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1559 }
1560 }
1561 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
1562 CHECK_VAR(y, Bounds(cache.kAsmFloat));
1563 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
1564 CHECK_VAR(fround, FUNC_N2F_TYPE);
1565 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
1566 }
1567 }
1568 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
1569 CHECK_EXPR(Property, Bounds::Unbounded()) {
1570 CHECK_VAR(f32, Bounds(cache.kFloat32Array));
1571 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1572 }
1573 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmFloat)) {
1574 CHECK_VAR(x, Bounds(cache.kAsmFloat));
1575 CHECK_VAR(y, Bounds(cache.kAsmFloat));
1576 }
1577 }
1578 }
1579 CHECK_SKIP();
1580 }
1581 CHECK_FUNC_TYPES_END
1582}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001583
1584TEST(Load1Constant) {
1585 CHECK_FUNC_TYPES_BEGIN(
1586 "function bar() { var x = 1; var y = i8[5]|0; }\n"
1587 "function foo() { bar(); }") {
1588 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1589 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1590 CHECK_VAR(x, Bounds(cache.kAsmInt));
1591 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1592 }
1593 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1594 CHECK_VAR(y, Bounds(cache.kAsmInt));
1595 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1596 CHECK_EXPR(Property, Bounds(cache.kAsmInt)) {
1597 CHECK_VAR(i8, Bounds(cache.kInt8Array));
1598 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1599 }
1600 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1601 }
1602 }
1603 }
1604 CHECK_SKIP();
1605 }
1606 CHECK_FUNC_TYPES_END
1607}
1608
1609
1610TEST(FunctionTables) {
1611 CHECK_FUNC_TYPES_BEGIN(
1612 "function func1(x) { x = x | 0; return (x * 5) | 0; }\n"
1613 "function func2(x) { x = x | 0; return (x * 25) | 0; }\n"
1614 "var table1 = [func1, func2];\n"
1615 "function bar(x, y) { x = x | 0; y = y | 0;\n"
1616 " return table1[x & 1](y)|0; }\n"
1617 "function foo() { bar(1, 2); }") {
1618 CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) {
1619 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1620 CHECK_VAR(x, Bounds(cache.kAsmInt));
1621 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1622 CHECK_VAR(x, Bounds(cache.kAsmInt));
1623 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1624 }
1625 }
1626 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1627 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
1628 CHECK_VAR(x, Bounds(cache.kAsmInt));
1629 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1630 }
1631 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1632 }
1633 }
1634 CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) {
1635 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1636 CHECK_VAR(x, Bounds(cache.kAsmInt));
1637 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1638 CHECK_VAR(x, Bounds(cache.kAsmInt));
1639 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1640 }
1641 }
1642 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1643 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
1644 CHECK_VAR(x, Bounds(cache.kAsmInt));
1645 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1646 }
1647 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1648 }
1649 }
1650 CHECK_EXPR(FunctionLiteral, FUNC_II2I_TYPE) {
1651 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1652 CHECK_VAR(x, Bounds(cache.kAsmInt));
1653 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1654 CHECK_VAR(x, Bounds(cache.kAsmInt));
1655 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1656 }
1657 }
1658 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1659 CHECK_VAR(y, Bounds(cache.kAsmInt));
1660 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1661 CHECK_VAR(y, Bounds(cache.kAsmInt));
1662 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1663 }
1664 }
1665 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
1666 CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
1667 CHECK_EXPR(Property, FUNC_I2I_TYPE) {
1668 CHECK_VAR(table1, FUNC_I2I_ARRAY_TYPE);
1669 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001670 // TODO(bradnelson): revert this
1671 // CHECK_VAR(x, Bounds(cache.kAsmSigned));
1672 CHECK_VAR(x, Bounds(cache.kAsmInt));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001673 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1674 }
1675 }
1676 CHECK_VAR(y, Bounds(cache.kAsmInt));
1677 }
1678 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1679 }
1680 }
1681 CHECK_SKIP();
1682 }
1683 CHECK_FUNC_TYPES_END_1();
1684 CHECK_EXPR(Assignment, FUNC_I2I_ARRAY_TYPE) {
1685 CHECK_VAR(table1, FUNC_I2I_ARRAY_TYPE);
1686 CHECK_EXPR(ArrayLiteral, FUNC_I2I_ARRAY_TYPE) {
1687 CHECK_VAR(func1, FUNC_I2I_TYPE);
1688 CHECK_VAR(func2, FUNC_I2I_TYPE);
1689 }
1690 }
1691 CHECK_FUNC_TYPES_END_2();
1692}
1693
1694
1695TEST(BadFunctionTable) {
1696 CHECK_FUNC_ERROR(
1697 "function func1(x) { x = x | 0; return (x * 5) | 0; }\n"
1698 "var table1 = [func1, 1];\n"
1699 "function bar(x, y) { x = x | 0; y = y | 0;\n"
1700 " return table1[x & 1](y)|0; }\n"
1701 "function foo() { bar(1, 2); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001702 "asm: line 2: array component expected to be a function\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001703}
1704
1705
1706TEST(MissingParameterTypes) {
1707 CHECK_FUNC_ERROR(
1708 "function bar(x) { var y = 1; }\n"
1709 "function foo() { bar(2); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001710 "asm: line 1: missing parameter type annotations\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001711}
1712
1713
1714TEST(InvalidTypeAnnotationBinaryOpDiv) {
1715 CHECK_FUNC_ERROR(
1716 "function bar(x) { x = x / 4; }\n"
1717 "function foo() { bar(2); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001718 "asm: line 1: invalid type annotation on binary op\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001719}
1720
1721
1722TEST(InvalidTypeAnnotationBinaryOpMul) {
1723 CHECK_FUNC_ERROR(
1724 "function bar(x) { x = x * 4.0; }\n"
1725 "function foo() { bar(2); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001726 "asm: line 1: invalid type annotation on binary op\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001727}
1728
1729
1730TEST(InvalidArgumentCount) {
1731 CHECK_FUNC_ERROR(
1732 "function bar(x) { return fround(4, 5); }\n"
1733 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001734 "asm: line 1: invalid argument count calling function\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001735}
1736
1737
1738TEST(InvalidTypeAnnotationArity) {
1739 CHECK_FUNC_ERROR(
1740 "function bar(x) { x = max(x); }\n"
1741 "function foo() { bar(3); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001742 "asm: line 1: only fround allowed on expression annotations\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001743}
1744
1745
1746TEST(InvalidTypeAnnotationOnlyFround) {
1747 CHECK_FUNC_ERROR(
1748 "function bar(x) { x = sin(x); }\n"
1749 "function foo() { bar(3); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001750 "asm: line 1: only fround allowed on expression annotations\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001751}
1752
1753
1754TEST(InvalidTypeAnnotation) {
1755 CHECK_FUNC_ERROR(
1756 "function bar(x) { x = (x+x)(x); }\n"
1757 "function foo() { bar(3); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001758 "asm: line 1: invalid type annotation\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001759}
1760
1761
1762TEST(WithStatement) {
1763 CHECK_FUNC_ERROR(
1764 "function bar() { var x = 0; with (x) { x = x + 1; } }\n"
1765 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001766 "asm: line 1: bad with statement\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001767}
1768
1769
1770TEST(NestedFunction) {
1771 CHECK_FUNC_ERROR(
1772 "function bar() { function x() { return 1; } }\n"
1773 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001774 "asm: line 1: function declared inside another\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001775}
1776
1777
1778TEST(UnboundVariable) {
1779 CHECK_FUNC_ERROR(
1780 "function bar() { var x = y; }\n"
1781 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001782 "asm: line 1: unbound variable\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001783}
1784
1785
1786TEST(EqStrict) {
1787 CHECK_FUNC_ERROR(
1788 "function bar() { return (0 === 0)|0; }\n"
1789 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001790 "asm: line 1: illegal comparison operator\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001791}
1792
1793
1794TEST(NeStrict) {
1795 CHECK_FUNC_ERROR(
1796 "function bar() { return (0 !== 0)|0; }\n"
1797 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001798 "asm: line 1: illegal comparison operator\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001799}
1800
1801
1802TEST(InstanceOf) {
1803 CHECK_FUNC_ERROR(
1804 "function bar() { return (0 instanceof 0)|0; }\n"
1805 "function foo() { bar(); }",
Ben Murdochc5610432016-08-08 18:44:38 +01001806 "asm: line 1: illegal comparison operator\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001807}
1808
1809
1810TEST(InOperator) {
1811 CHECK_FUNC_ERROR(
1812 "function bar() { return (0 in 0)|0; }\n"
1813 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001814 "asm: line 1: illegal comparison operator\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001815}
1816
1817
1818TEST(LogicalAndOperator) {
1819 CHECK_FUNC_ERROR(
1820 "function bar() { return (0 && 0)|0; }\n"
1821 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001822 "asm: line 1: illegal logical operator\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001823}
1824
1825
1826TEST(LogicalOrOperator) {
1827 CHECK_FUNC_ERROR(
1828 "function bar() { return (0 || 0)|0; }\n"
1829 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001830 "asm: line 1: illegal logical operator\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001831}
1832
Ben Murdochda12d292016-06-02 14:46:10 +01001833TEST(BitOrDouble) {
1834 CHECK_FUNC_ERROR(
1835 "function bar() { var x = 1.0; return x | 0; }\n"
1836 "function foo() { bar(); }",
1837 "asm: line 1: intish required\n");
1838}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001839
1840TEST(BadLiteral) {
1841 CHECK_FUNC_ERROR(
1842 "function bar() { return true | 0; }\n"
1843 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001844 "asm: line 1: illegal literal\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001845}
1846
1847
1848TEST(MismatchedReturnTypeLiteral) {
1849 CHECK_FUNC_ERROR(
1850 "function bar() { if(1) { return 1; } return 1.0; }\n"
1851 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001852 "asm: line 1: return type does not match function signature\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001853}
1854
1855
1856TEST(MismatchedReturnTypeExpression) {
1857 CHECK_FUNC_ERROR(
1858 "function bar() {\n"
1859 " var x = 1; var y = 1.0; if(1) { return x; } return +y; }\n"
1860 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001861 "asm: line 2: return type does not match function signature\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001862}
1863
1864
1865TEST(AssignToFloatishToF64) {
1866 CHECK_FUNC_ERROR(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001867 "function bar() { var v = fround(1.0); f64[0] = v + fround(1.0); }\n"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001868 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001869 "asm: line 1: floatish assignment to double array\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001870}
1871
1872
1873TEST(ForeignFunction) {
1874 CHECK_FUNC_TYPES_BEGIN(
1875 "var baz = foreign.baz;\n"
1876 "function bar() { return baz(1, 2)|0; }\n"
1877 "function foo() { bar(); }") {
1878 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
1879 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001880 CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
1881 CHECK_VAR(baz, FUNC_FOREIGN_TYPE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001882 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1883 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1884 }
1885 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1886 }
1887 }
1888 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1889 CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
1890 CHECK_VAR(bar, FUNC_I_TYPE);
1891 }
1892 }
1893 }
1894 CHECK_FUNC_TYPES_END_1()
Ben Murdoch097c5b22016-05-18 11:27:45 +01001895 CHECK_EXPR(Assignment, Bounds(FUNC_FOREIGN_TYPE)) {
1896 CHECK_VAR(baz, Bounds(FUNC_FOREIGN_TYPE));
1897 CHECK_EXPR(Property, Bounds(FUNC_FOREIGN_TYPE)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001898 CHECK_VAR(foreign, Bounds::Unbounded());
1899 CHECK_EXPR(Literal, Bounds::Unbounded());
1900 }
1901 }
1902 CHECK_FUNC_TYPES_END_2()
1903}
1904
Ben Murdoch097c5b22016-05-18 11:27:45 +01001905TEST(ByteArray) {
1906 // Forbidden by asm.js spec, present in embenchen.
1907 CHECK_FUNC_TYPES_BEGIN(
1908 "function bar() { var x = 0; i8[x] = 2; }\n"
1909 "function foo() { bar(); }") {
1910 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
1911 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1912 CHECK_VAR(x, Bounds(cache.kAsmInt));
1913 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1914 }
1915 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
1916 CHECK_EXPR(Property, Bounds::Unbounded()) {
1917 CHECK_VAR(i8, Bounds(cache.kInt8Array));
1918 CHECK_VAR(x, Bounds(cache.kAsmSigned));
1919 }
1920 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
1921 }
1922 }
1923 CHECK_SKIP();
1924 }
1925 CHECK_FUNC_TYPES_END
1926}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001927
1928TEST(BadExports) {
1929 HARNESS_PREAMBLE()
1930 "function foo() {};\n"
1931 "return {foo: foo, bar: 1};"
1932 "}\n";
1933
1934 v8::V8::Initialize();
1935 HandleAndZoneScope handles;
1936 Zone* zone = handles.main_zone();
1937 ZoneVector<ExpressionTypeEntry> types(zone);
Ben Murdochda12d292016-06-02 14:46:10 +01001938 CHECK_EQ("asm: line 2: non-function in function table\n",
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001939 Validate(zone, test_function, &types));
1940}
1941
1942
1943TEST(NestedHeapAssignment) {
1944 CHECK_FUNC_ERROR(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001945 "function bar() { var x = 0; i16[x = 1] = 2; }\n"
1946 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001947 "asm: line 1: expected >> in heap access\n");
Ben Murdoch097c5b22016-05-18 11:27:45 +01001948}
1949
1950TEST(BadOperatorHeapAssignment) {
1951 CHECK_FUNC_ERROR(
1952 "function bar() { var x = 0; i16[x & 1] = 2; }\n"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001953 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001954 "asm: line 1: expected >> in heap access\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001955}
1956
1957
1958TEST(BadArrayAssignment) {
1959 CHECK_FUNC_ERROR(
1960 "function bar() { i8[0] = 0.0; }\n"
1961 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001962 "asm: line 1: illegal type in assignment\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001963}
1964
1965
1966TEST(BadStandardFunctionCallOutside) {
1967 CHECK_FUNC_ERROR(
1968 "var s0 = sin(0);\n"
1969 "function bar() { }\n"
1970 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001971 "asm: line 1: illegal variable reference in module body\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001972}
1973
1974
1975TEST(BadFunctionCallOutside) {
1976 CHECK_FUNC_ERROR(
1977 "function bar() { return 0.0; }\n"
1978 "var s0 = bar(0);\n"
1979 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01001980 "asm: line 2: illegal variable reference in module body\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001981}
1982
Ben Murdochda12d292016-06-02 14:46:10 +01001983TEST(UnaryPlusOnIntForbidden) {
1984 CHECK_FUNC_ERROR(
1985 "function bar() { var x = 1; return +x; }\n"
1986 "function foo() { bar(); }",
1987 "asm: line 1: "
1988 "unary + only allowed on signed, unsigned, float?, or double?\n");
1989}
1990
1991TEST(MultiplyNon1ConvertForbidden) {
1992 CHECK_FUNC_ERROR(
1993 "function bar() { var x = 0.0; return x * 2.0; }\n"
1994 "function foo() { bar(); }",
1995 "asm: line 1: invalid type annotation on binary op\n");
1996}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001997
1998TEST(NestedVariableAssignment) {
1999 CHECK_FUNC_TYPES_BEGIN(
2000 "function bar() { var x = 0; x = x = 4; }\n"
2001 "function foo() { bar(); }") {
2002 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
2003 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
2004 CHECK_VAR(x, Bounds(cache.kAsmInt));
2005 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2006 }
2007 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
2008 CHECK_VAR(x, Bounds(cache.kAsmInt));
2009 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
2010 CHECK_VAR(x, Bounds(cache.kAsmInt));
2011 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2012 }
2013 }
2014 }
2015 CHECK_SKIP();
2016 }
2017 CHECK_FUNC_TYPES_END
2018}
2019
2020
2021TEST(NestedAssignmentInHeap) {
2022 CHECK_FUNC_TYPES_BEGIN(
2023 "function bar() { var x = 0; i8[(x = 1) >> 0] = 2; }\n"
2024 "function foo() { bar(); }") {
2025 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
2026 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
2027 CHECK_VAR(x, Bounds(cache.kAsmInt));
2028 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2029 }
2030 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
2031 CHECK_EXPR(Property, Bounds::Unbounded()) {
2032 CHECK_VAR(i8, Bounds(cache.kInt8Array));
2033 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002034 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002035 CHECK_VAR(x, Bounds(cache.kAsmInt));
2036 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2037 }
2038 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2039 }
2040 }
2041 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2042 }
2043 }
2044 CHECK_SKIP();
2045 }
2046 CHECK_FUNC_TYPES_END
2047}
2048
2049
2050TEST(NegativeDouble) {
2051 CHECK_FUNC_TYPES_BEGIN(
2052 "function bar() { var x = -123.2; }\n"
2053 "function foo() { bar(); }") {
2054 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
2055 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
2056 CHECK_VAR(x, Bounds(cache.kAsmDouble));
2057 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2058 }
2059 }
2060 CHECK_SKIP();
2061 }
2062 CHECK_FUNC_TYPES_END
2063}
2064
2065
2066TEST(NegativeInteger) {
2067 CHECK_FUNC_TYPES_BEGIN(
2068 "function bar() { var x = -123; }\n"
2069 "function foo() { bar(); }") {
2070 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
2071 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
2072 CHECK_VAR(x, Bounds(cache.kAsmInt));
2073 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
2074 }
2075 }
2076 CHECK_SKIP();
2077 }
2078 CHECK_FUNC_TYPES_END
2079}
2080
2081
2082TEST(AbsFunction) {
2083 CHECK_FUNC_TYPES_BEGIN(
2084 "function bar() { var x = -123.0; x = abs(x); }\n"
2085 "function foo() { bar(); }") {
2086 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
2087 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
2088 CHECK_VAR(x, Bounds(cache.kAsmDouble));
2089 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2090 }
2091 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
2092 CHECK_VAR(x, Bounds(cache.kAsmDouble));
2093 CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
2094 CHECK_VAR(abs, FUNC_N2N_TYPE);
2095 CHECK_VAR(x, Bounds(cache.kAsmDouble));
2096 }
2097 }
2098 }
2099 CHECK_SKIP();
2100 }
2101 CHECK_FUNC_TYPES_END
2102}
2103
2104
2105TEST(CeilFloat) {
2106 CHECK_FUNC_TYPES_BEGIN(
2107 "function bar() { var x = fround(3.1); x = ceil(x); }\n"
2108 "function foo() { bar(); }") {
2109 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
2110 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
2111 CHECK_VAR(x, Bounds(cache.kAsmFloat));
2112 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
2113 CHECK_VAR(fround, FUNC_N2F_TYPE);
2114 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2115 }
2116 }
2117 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
2118 CHECK_VAR(x, Bounds(cache.kAsmFloat));
2119 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
2120 CHECK_VAR(ceil, FUNC_N2N_TYPE);
2121 CHECK_VAR(x, Bounds(cache.kAsmFloat));
2122 }
2123 }
2124 }
2125 CHECK_SKIP();
2126 }
2127 CHECK_FUNC_TYPES_END
2128}
2129
Ben Murdochda12d292016-06-02 14:46:10 +01002130TEST(FloatReturnAsDouble) {
2131 CHECK_FUNC_TYPES_BEGIN(
2132 "function bar() { var x = fround(3.1); return +fround(x); }\n"
2133 "function foo() { bar(); }") {
2134 CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) {
2135 CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
2136 CHECK_VAR(x, Bounds(cache.kAsmFloat));
2137 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
2138 CHECK_VAR(fround, FUNC_N2F_TYPE);
2139 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2140 }
2141 }
2142 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
2143 CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
2144 CHECK_VAR(fround, FUNC_N2F_TYPE);
2145 CHECK_VAR(x, Bounds(cache.kAsmFloat));
2146 }
2147 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2148 }
2149 }
2150 CHECK_SKIP();
2151 }
2152 CHECK_FUNC_TYPES_END
2153}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002154
2155TEST(TypeConsistency) {
2156 v8::V8::Initialize();
2157 TypeCache cache;
2158 // Check the consistency of each of the main Asm.js types.
2159 CHECK(cache.kAsmFixnum->Is(cache.kAsmFixnum));
2160 CHECK(cache.kAsmFixnum->Is(cache.kAsmSigned));
2161 CHECK(cache.kAsmFixnum->Is(cache.kAsmUnsigned));
2162 CHECK(cache.kAsmFixnum->Is(cache.kAsmInt));
2163 CHECK(!cache.kAsmFixnum->Is(cache.kAsmFloat));
2164 CHECK(!cache.kAsmFixnum->Is(cache.kAsmDouble));
2165
2166 CHECK(cache.kAsmSigned->Is(cache.kAsmSigned));
2167 CHECK(cache.kAsmSigned->Is(cache.kAsmInt));
2168 CHECK(!cache.kAsmSigned->Is(cache.kAsmFixnum));
2169 CHECK(!cache.kAsmSigned->Is(cache.kAsmUnsigned));
2170 CHECK(!cache.kAsmSigned->Is(cache.kAsmFloat));
2171 CHECK(!cache.kAsmSigned->Is(cache.kAsmDouble));
2172
2173 CHECK(cache.kAsmUnsigned->Is(cache.kAsmUnsigned));
2174 CHECK(cache.kAsmUnsigned->Is(cache.kAsmInt));
2175 CHECK(!cache.kAsmUnsigned->Is(cache.kAsmSigned));
2176 CHECK(!cache.kAsmUnsigned->Is(cache.kAsmFixnum));
2177 CHECK(!cache.kAsmUnsigned->Is(cache.kAsmFloat));
2178 CHECK(!cache.kAsmUnsigned->Is(cache.kAsmDouble));
2179
2180 CHECK(cache.kAsmInt->Is(cache.kAsmInt));
2181 CHECK(!cache.kAsmInt->Is(cache.kAsmUnsigned));
2182 CHECK(!cache.kAsmInt->Is(cache.kAsmSigned));
2183 CHECK(!cache.kAsmInt->Is(cache.kAsmFixnum));
2184 CHECK(!cache.kAsmInt->Is(cache.kAsmFloat));
2185 CHECK(!cache.kAsmInt->Is(cache.kAsmDouble));
2186
2187 CHECK(cache.kAsmFloat->Is(cache.kAsmFloat));
2188 CHECK(!cache.kAsmFloat->Is(cache.kAsmInt));
2189 CHECK(!cache.kAsmFloat->Is(cache.kAsmUnsigned));
2190 CHECK(!cache.kAsmFloat->Is(cache.kAsmSigned));
2191 CHECK(!cache.kAsmFloat->Is(cache.kAsmFixnum));
2192 CHECK(!cache.kAsmFloat->Is(cache.kAsmDouble));
2193
2194 CHECK(cache.kAsmDouble->Is(cache.kAsmDouble));
2195 CHECK(!cache.kAsmDouble->Is(cache.kAsmInt));
2196 CHECK(!cache.kAsmDouble->Is(cache.kAsmUnsigned));
2197 CHECK(!cache.kAsmDouble->Is(cache.kAsmSigned));
2198 CHECK(!cache.kAsmDouble->Is(cache.kAsmFixnum));
2199 CHECK(!cache.kAsmDouble->Is(cache.kAsmFloat));
2200}
2201
2202
2203TEST(SwitchTest) {
2204 CHECK_FUNC_TYPES_BEGIN(
2205 "function switcher(x) {\n"
2206 " x = x|0;\n"
2207 " switch (x|0) {\n"
2208 " case 1: return 23;\n"
2209 " case 2: return 43;\n"
2210 " default: return 66;\n"
2211 " }\n"
2212 " return 0;\n"
2213 "}\n"
2214 "function foo() { switcher(1); }") {
2215 CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) {
2216 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
2217 CHECK_VAR(x, Bounds(cache.kAsmInt));
2218 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
2219 CHECK_VAR(x, Bounds(cache.kAsmInt));
2220 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2221 }
2222 }
2223 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
2224 CHECK_VAR(.switch_tag, Bounds(cache.kAsmInt));
2225 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
2226 CHECK_VAR(x, Bounds(cache.kAsmInt));
2227 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2228 }
2229 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002230 CHECK_EXPR(Literal, Bounds(Type::Undefined()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002231 CHECK_VAR(.switch_tag, Bounds(cache.kAsmSigned));
2232 // case 1: return 23;
2233 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2234 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
2235 // case 2: return 43;
2236 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2237 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
2238 // default: return 66;
2239 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
2240 // return 0;
2241 CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
2242 }
2243 CHECK_SKIP();
2244 }
2245 CHECK_FUNC_TYPES_END
2246}
2247
2248
2249TEST(BadSwitchRange) {
2250 CHECK_FUNC_ERROR(
2251 "function bar() { switch (1) { case -1: case 0x7fffffff: } }\n"
2252 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01002253 "asm: line 1: case range too large\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002254}
2255
2256
2257TEST(DuplicateSwitchCase) {
2258 CHECK_FUNC_ERROR(
2259 "function bar() { switch (1) { case 0: case 0: } }\n"
2260 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01002261 "asm: line 1: duplicate case value\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002262}
2263
2264
2265TEST(BadSwitchOrder) {
2266 CHECK_FUNC_ERROR(
2267 "function bar() { switch (1) { default: case 0: } }\n"
2268 "function foo() { bar(); }",
Ben Murdochda12d292016-06-02 14:46:10 +01002269 "asm: line 1: default case out of order\n");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002270}
Ben Murdoch097c5b22016-05-18 11:27:45 +01002271
2272TEST(BadForeignCall) {
2273 const char test_function[] =
2274 "function TestModule(stdlib, foreign, buffer) {\n"
2275 " \"use asm\";\n"
2276 " var ffunc = foreign.foo;\n"
2277 " function test1() { var x = 0; ffunc(x); }\n"
2278 " return { testFunc1: test1 };\n"
2279 "}\n";
2280 v8::V8::Initialize();
2281 HandleAndZoneScope handles;
2282 Zone* zone = handles.main_zone();
2283 ZoneVector<ExpressionTypeEntry> types(zone);
2284 CHECK_EQ(
2285 "asm: line 4: foreign call argument expected to be int, double, or "
2286 "fixnum\n",
2287 Validate(zone, test_function, &types));
2288}
2289
2290TEST(BadImports) {
2291 const char test_function[] =
2292 "function TestModule(stdlib, foreign, buffer) {\n"
2293 " \"use asm\";\n"
2294 " var fint = (foreign.bar | 0) | 0;\n"
2295 " function test1() {}\n"
2296 " return { testFunc1: test1 };\n"
2297 "}\n";
2298 v8::V8::Initialize();
2299 HandleAndZoneScope handles;
2300 Zone* zone = handles.main_zone();
2301 ZoneVector<ExpressionTypeEntry> types(zone);
2302 CHECK_EQ("asm: line 3: illegal computation inside module body\n",
2303 Validate(zone, test_function, &types));
2304}
2305
2306TEST(BadVariableReference) {
2307 const char test_function[] =
2308 "function TestModule(stdlib, foreign, buffer) {\n"
2309 " \"use asm\";\n"
2310 " var x = 0;\n"
2311 " var y = x;\n"
2312 " function test1() {}\n"
2313 " return { testFunc1: test1 };\n"
2314 "}\n";
2315 v8::V8::Initialize();
2316 HandleAndZoneScope handles;
2317 Zone* zone = handles.main_zone();
2318 ZoneVector<ExpressionTypeEntry> types(zone);
2319 CHECK_EQ("asm: line 4: illegal variable reference in module body\n",
2320 Validate(zone, test_function, &types));
2321}
2322
2323TEST(BadForeignVariableReferenceValueOr) {
2324 const char test_function[] =
2325 "function TestModule(stdlib, foreign, buffer) {\n"
2326 " \"use asm\";\n"
2327 " var fint = foreign.bar | 1;\n"
2328 "}\n";
2329 v8::V8::Initialize();
2330 HandleAndZoneScope handles;
2331 Zone* zone = handles.main_zone();
2332 ZoneVector<ExpressionTypeEntry> types(zone);
2333 CHECK_EQ("asm: line 3: illegal integer annotation value\n",
2334 Validate(zone, test_function, &types));
2335}
2336
2337TEST(BadForeignVariableReferenceValueOrDot) {
2338 const char test_function[] =
2339 "function TestModule(stdlib, foreign, buffer) {\n"
2340 " \"use asm\";\n"
2341 " var fint = foreign.bar | 1.0;\n"
2342 "}\n";
2343 v8::V8::Initialize();
2344 HandleAndZoneScope handles;
2345 Zone* zone = handles.main_zone();
2346 ZoneVector<ExpressionTypeEntry> types(zone);
2347 CHECK_EQ("asm: line 3: illegal integer annotation value\n",
2348 Validate(zone, test_function, &types));
2349}
2350
2351TEST(BadForeignVariableReferenceValueMul) {
2352 const char test_function[] =
2353 "function TestModule(stdlib, foreign, buffer) {\n"
2354 " \"use asm\";\n"
2355 " var fint = foreign.bar * 2.0;\n"
2356 "}\n";
2357 v8::V8::Initialize();
2358 HandleAndZoneScope handles;
2359 Zone* zone = handles.main_zone();
2360 ZoneVector<ExpressionTypeEntry> types(zone);
2361 CHECK_EQ("asm: line 3: illegal double annotation value\n",
2362 Validate(zone, test_function, &types));
2363}
2364
2365TEST(BadForeignVariableReferenceValueMulNoDot) {
2366 const char test_function[] =
2367 "function TestModule(stdlib, foreign, buffer) {\n"
2368 " \"use asm\";\n"
2369 " var fint = foreign.bar * 1;\n"
2370 "}\n";
2371 v8::V8::Initialize();
2372 HandleAndZoneScope handles;
2373 Zone* zone = handles.main_zone();
2374 ZoneVector<ExpressionTypeEntry> types(zone);
2375 CHECK_EQ("asm: line 3: ill-typed arithmetic operation\n",
2376 Validate(zone, test_function, &types));
2377}
2378
2379TEST(Imports) {
2380 const char test_function[] =
2381 "function TestModule(stdlib, foreign, buffer) {\n"
2382 " \"use asm\";\n"
2383 " var ffunc = foreign.foo;\n"
2384 " var fint = foreign.bar | 0;\n"
2385 " var fdouble = +foreign.baz;\n"
2386 " function test1() { return ffunc(fint|0, fdouble) | 0; }\n"
2387 " function test2() { return +ffunc(fdouble, fint|0); }\n"
2388 " return { testFunc1: test1, testFunc2: test2 };\n"
2389 "}\n";
2390
2391 v8::V8::Initialize();
2392 HandleAndZoneScope handles;
2393 Zone* zone = handles.main_zone();
2394 ZoneVector<ExpressionTypeEntry> types(zone);
2395 CHECK_EQ("", Validate(zone, test_function, &types));
2396 TypeCache cache;
2397
2398 CHECK_TYPES_BEGIN {
2399 // Module.
2400 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
2401 // function test1
2402 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
2403 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
2404 CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
2405 CHECK_VAR(ffunc, FUNC_FOREIGN_TYPE);
2406 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
2407 CHECK_VAR(fint, Bounds(cache.kAsmInt));
2408 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2409 }
2410 CHECK_VAR(fdouble, Bounds(cache.kAsmDouble));
2411 }
2412 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2413 }
2414 }
2415 // function test2
2416 CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) {
2417 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
2418 CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
2419 CHECK_VAR(ffunc, FUNC_FOREIGN_TYPE);
2420 CHECK_VAR(fdouble, Bounds(cache.kAsmDouble));
2421 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
2422 CHECK_VAR(fint, Bounds(cache.kAsmInt));
2423 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2424 }
2425 }
2426 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2427 }
2428 }
2429 // "use asm";
2430 CHECK_EXPR(Literal, Bounds(Type::String()));
2431 // var func = foreign.foo;
2432 CHECK_EXPR(Assignment, Bounds(FUNC_FOREIGN_TYPE)) {
2433 CHECK_VAR(ffunc, Bounds(FUNC_FOREIGN_TYPE));
2434 CHECK_EXPR(Property, Bounds(FUNC_FOREIGN_TYPE)) {
2435 CHECK_VAR(foreign, Bounds::Unbounded());
2436 CHECK_EXPR(Literal, Bounds::Unbounded());
2437 }
2438 }
2439 // var fint = foreign.bar | 0;
2440 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
2441 CHECK_VAR(fint, Bounds(cache.kAsmInt));
2442 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
2443 CHECK_EXPR(Property, Bounds(Type::Number())) {
2444 CHECK_VAR(foreign, Bounds::Unbounded());
2445 CHECK_EXPR(Literal, Bounds::Unbounded());
2446 }
2447 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2448 }
2449 }
2450 // var fdouble = +foreign.baz;
2451 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
2452 CHECK_VAR(fdouble, Bounds(cache.kAsmDouble));
2453 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
2454 CHECK_EXPR(Property, Bounds(Type::Number())) {
2455 CHECK_VAR(foreign, Bounds::Unbounded());
2456 CHECK_EXPR(Literal, Bounds::Unbounded());
2457 }
2458 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2459 }
2460 }
2461 // return { testFunc1: test1, testFunc2: test2 };
2462 CHECK_EXPR(ObjectLiteral, Bounds::Unbounded()) {
2463 CHECK_VAR(test1, FUNC_I_TYPE);
2464 CHECK_VAR(test2, FUNC_D_TYPE);
2465 }
2466 }
2467 }
2468 CHECK_TYPES_END
2469}
Ben Murdochda12d292016-06-02 14:46:10 +01002470
2471TEST(StoreFloatFromDouble) {
2472 CHECK_FUNC_TYPES_BEGIN(
2473 "function bar() { f32[0] = 0.0; }\n"
2474 "function foo() { bar(); }") {
2475 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
2476 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
2477 CHECK_EXPR(Property, Bounds::Unbounded()) {
2478 CHECK_VAR(f32, Bounds(cache.kFloat32Array));
2479 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
2480 }
2481 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2482 }
2483 }
2484 CHECK_SKIP();
2485 }
2486 CHECK_FUNC_TYPES_END
2487}
2488
2489TEST(NegateDouble) {
2490 CHECK_FUNC_TYPES_BEGIN(
2491 "function bar() { var x = 0.0; x = -x; }\n"
2492 "function foo() { bar(); }") {
2493 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
2494 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
2495 CHECK_VAR(x, Bounds(cache.kAsmDouble));
2496 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2497 }
2498 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
2499 CHECK_VAR(x, Bounds(cache.kAsmDouble));
2500 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
2501 CHECK_VAR(x, Bounds(cache.kAsmDouble));
2502 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
2503 }
2504 }
2505 }
2506 CHECK_SKIP();
2507 }
2508 CHECK_FUNC_TYPES_END
2509}