v8/test/mjsunit/asm/call-annotation.js
Michael Starzinger f09460389b [asm.js] Test and fix "|0" annotation of calls.
This fixes the validation of "|0" annotations of call sites that are
used to indicate a "signed" return type of functions. We use lookahead
during call validation and request deferred validation as part of the
actual OR-expression. Special care has to be taken to get precedence
levels of all involved operators right.

R=clemensh@chromium.org
TEST=mjsunit/asm/call-annotation
BUG=v8:6183

Change-Id: If0586f669e7cee26a13425b0fd9f41098e852d68
Reviewed-on: https://chromium-review.googlesource.com/475871
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44639}
2017-04-13 10:38:22 +00:00

180 lines
4.1 KiB
JavaScript

// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --validate-asm
// This file contains test cases that are particularly interesting for a single
// pass asm.js parsing and validation implementation in regards to the return
// type annotation via the "|0" operation.
var g_was_called = 0;
function g() {
g_was_called++;
return "23.4";
}
(function SuccessExternCoercion() {
function Module(stdlib, imports, heap) {
"use asm";
var g = imports.g;
function f(a) {
a = a | 0;
a = a + (g() | 0) | 0;
return a | 0;
}
return { f:f };
}
g_was_called = 0;
var m = Module(this, { g:g });
assertTrue(%IsAsmWasmCode(Module));
assertEquals(24, m.f(1));
assertEquals(1, g_was_called);
})();
(function FailPrecedenceLeftStronger() {
function Module(stdlib, imports, heap) {
"use asm";
var g = imports.g;
function f(a) {
a = a | 0;
a = a + g() | 0;
return a | 0;
}
return { f:f };
}
g_was_called = 0;
var m = Module(this, { g:g });
assertFalse(%IsAsmWasmCode(Module));
assertEquals(123, m.f(1));
assertEquals(1, g_was_called);
})();
(function FailPrecedenceRightStronger() {
function Module(stdlib, imports, heap) {
"use asm";
var g = imports.g;
function f(a) {
a = a | 0;
a = (g() | 0 + a) | 0;
return a | 0;
}
return { f:f };
}
g_was_called = 0;
var m = Module(this, { g:g });
assertFalse(%IsAsmWasmCode(Module));
assertEquals(127, m.f(127));
assertEquals(1, g_was_called);
})();
(function FailParenthesizedAnnotation() {
function Module(stdlib, imports, heap) {
"use asm";
var g = imports.g;
function f(a) {
a = a | 0;
a = (g()) | 0;
return a | 0;
}
return { f:f };
}
g_was_called = 0;
var m = Module(this, { g:g });
// TODO(6127): Only properly rejected by "new" parser.
// assertFalse(%IsAsmWasmCode(Module));
assertEquals(23, m.f(1));
assertEquals(1, g_was_called);
})();
(function FailNonZeroAnnotation() {
function Module(stdlib, imports, heap) {
"use asm";
var g = imports.g;
function f(a) {
a = a | 0;
a = g() | 127;
return a | 0;
}
return { f:f };
}
g_was_called = 0;
var m = Module(this, { g:g });
assertFalse(%IsAsmWasmCode(Module));
assertEquals(127, m.f(1));
assertEquals(1, g_was_called);
})();
(function FailNestedAnnotation1() {
function Module(stdlib, imports, heap) {
"use asm";
var g = imports.g;
function f(a) {
a = a | 0;
a = g() | g() | 0;
return a | 0;
}
return { f:f };
}
g_was_called = 0;
var m = Module(this, { g:g });
assertFalse(%IsAsmWasmCode(Module));
assertEquals(23, m.f(1));
assertEquals(2, g_was_called);
})();
(function FailNestedAnnotation2() {
function Module(stdlib, imports, heap) {
"use asm";
var g = imports.g;
function f(a) {
a = a | 0;
a = g() | 0 | g() | 0;
return a | 0;
}
return { f:f };
}
g_was_called = 0;
var m = Module(this, { g:g });
assertFalse(%IsAsmWasmCode(Module));
assertEquals(23, m.f(1));
assertEquals(2, g_was_called);
})();
(function SuccessMixedWithDoubleAnnotation() {
function Module(stdlib, imports, heap) {
"use asm";
var g = imports.g;
function f(a) {
a = +a;
a = a + +(g() | 0);
return +a;
}
return { f:f };
}
g_was_called = 0;
var m = Module(this, { g:g });
assertTrue(%IsAsmWasmCode(Module));
assertEquals(23.5, m.f(0.5));
assertEquals(1, g_was_called);
})();
(function SuccessMixedWithFloatAnnotation() {
function Module(stdlib, imports, heap) {
"use asm";
var g = imports.g;
var fround = stdlib.Math.fround;
function f(a) {
a = fround(a);
a = fround(a + fround(g() | 0));
return fround(a);
}
return { f:f };
}
g_was_called = 0;
var m = Module(this, { g:g });
assertTrue(%IsAsmWasmCode(Module));
assertEquals(23.5, m.f(0.5));
assertEquals(1, g_was_called);
})();