f09460389b
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}
180 lines
4.1 KiB
JavaScript
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);
|
|
})();
|