Commit d175cefa authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[asm.js] Fix Math.ceil/floor/sqrt to return floatish.

This fixes the signatures of "Math.ceil", "Math.floor" and "Math.sqrt"
from "(float?) -> float" to "(float?) -> floatish" which avoids using a
resulting float value without coercing the value via explicit "fround"
annotations. This ensures proper ECMAScript semantics are maintained.

R=clemensh@chromium.org
TEST=mjsunit/regress/regress-6838-2
BUG=v8:6838

Change-Id: Ib5821641265bc862184adb270e8dbf8c703fdfb0
Reviewed-on: https://chromium-review.googlesource.com/681694Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48142}
parent 52e8d0ab
...@@ -103,9 +103,10 @@ void AsmJsParser::InitializeStdlibTypes() { ...@@ -103,9 +103,10 @@ void AsmJsParser::InitializeStdlibTypes() {
stdlib_dqdq2d_->AsFunctionType()->AddArgument(dq); stdlib_dqdq2d_->AsFunctionType()->AddArgument(dq);
auto* f = AsmType::Float(); auto* f = AsmType::Float();
auto* fh = AsmType::Floatish();
auto* fq = AsmType::FloatQ(); auto* fq = AsmType::FloatQ();
stdlib_fq2f_ = AsmType::Function(zone(), f); auto* fq2fh = AsmType::Function(zone(), fh);
stdlib_fq2f_->AsFunctionType()->AddArgument(fq); fq2fh->AsFunctionType()->AddArgument(fq);
auto* s = AsmType::Signed(); auto* s = AsmType::Signed();
auto* s2s = AsmType::Function(zone(), s); auto* s2s = AsmType::Function(zone(), s);
...@@ -132,14 +133,24 @@ void AsmJsParser::InitializeStdlibTypes() { ...@@ -132,14 +133,24 @@ void AsmJsParser::InitializeStdlibTypes() {
stdlib_minmax_->AsOverloadedFunctionType()->AddOverload(minmax_f); stdlib_minmax_->AsOverloadedFunctionType()->AddOverload(minmax_f);
stdlib_minmax_->AsOverloadedFunctionType()->AddOverload(minmax_d); stdlib_minmax_->AsOverloadedFunctionType()->AddOverload(minmax_d);
// The signatures in "9 Standard Library" of the spec draft are outdated and
// have been superseded with the following by an errata:
// TODO(mstarzinger): Actually fix Math.abs to return unsigned!
// - Math.abs : (signed) -> unsigned
// (double?) -> double
// (float?) -> floatish
stdlib_abs_ = AsmType::OverloadedFunction(zone()); stdlib_abs_ = AsmType::OverloadedFunction(zone());
stdlib_abs_->AsOverloadedFunctionType()->AddOverload(s2s); stdlib_abs_->AsOverloadedFunctionType()->AddOverload(s2s);
stdlib_abs_->AsOverloadedFunctionType()->AddOverload(stdlib_dq2d_); stdlib_abs_->AsOverloadedFunctionType()->AddOverload(stdlib_dq2d_);
stdlib_abs_->AsOverloadedFunctionType()->AddOverload(stdlib_fq2f_); stdlib_abs_->AsOverloadedFunctionType()->AddOverload(fq2fh);
// The signatures in "9 Standard Library" of the spec draft are outdated and
// have been superseded with the following by an errata:
// - Math.ceil/floor/sqrt : (double?) -> double
// (float?) -> floatish
stdlib_ceil_like_ = AsmType::OverloadedFunction(zone()); stdlib_ceil_like_ = AsmType::OverloadedFunction(zone());
stdlib_ceil_like_->AsOverloadedFunctionType()->AddOverload(stdlib_dq2d_); stdlib_ceil_like_->AsOverloadedFunctionType()->AddOverload(stdlib_dq2d_);
stdlib_ceil_like_->AsOverloadedFunctionType()->AddOverload(stdlib_fq2f_); stdlib_ceil_like_->AsOverloadedFunctionType()->AddOverload(fq2fh);
stdlib_fround_ = AsmType::FroundType(zone()); stdlib_fround_ = AsmType::FroundType(zone());
} }
...@@ -2203,6 +2214,9 @@ AsmType* AsmJsParser::ValidateCall() { ...@@ -2203,6 +2214,9 @@ AsmType* AsmJsParser::ValidateCall() {
} else if (callable->CanBeInvokedWith(AsmType::Float(), } else if (callable->CanBeInvokedWith(AsmType::Float(),
param_specific_types)) { param_specific_types)) {
return_type = AsmType::Float(); return_type = AsmType::Float();
} else if (callable->CanBeInvokedWith(AsmType::Floatish(),
param_specific_types)) {
return_type = AsmType::Floatish();
} else if (callable->CanBeInvokedWith(AsmType::Double(), } else if (callable->CanBeInvokedWith(AsmType::Double(),
param_specific_types)) { param_specific_types)) {
return_type = AsmType::Double(); return_type = AsmType::Double();
......
...@@ -183,7 +183,6 @@ class AsmJsParser { ...@@ -183,7 +183,6 @@ class AsmJsParser {
// Types used for stdlib function and their set up. // Types used for stdlib function and their set up.
AsmType* stdlib_dq2d_; AsmType* stdlib_dq2d_;
AsmType* stdlib_dqdq2d_; AsmType* stdlib_dqdq2d_;
AsmType* stdlib_fq2f_;
AsmType* stdlib_i2s_; AsmType* stdlib_i2s_;
AsmType* stdlib_ii2s_; AsmType* stdlib_ii2s_;
AsmType* stdlib_minmax_; AsmType* stdlib_minmax_;
......
// 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
(function TestMathCeilReturningFloatish() {
function Module(stdlib) {
"use asm";
var ceil = stdlib.Math.ceil;
var fround = stdlib.Math.fround;
function f(a) {
a = fround(a);
return ceil(a);
}
return f;
}
var f = Module(this);
assertEquals(3, f(2.2));
assertFalse(%IsAsmWasmCode(Module));
})();
(function TestMathFloorReturningFloatish() {
function Module(stdlib) {
"use asm";
var floor = stdlib.Math.floor;
var fround = stdlib.Math.fround;
function f(a) {
a = fround(a);
return floor(a);
}
return f;
}
var f = Module(this);
assertEquals(2, f(2.2));
assertFalse(%IsAsmWasmCode(Module));
})();
(function TestMathSqrtReturningFloatish() {
function Module(stdlib) {
"use asm";
var sqrt = stdlib.Math.sqrt;
var fround = stdlib.Math.fround;
function f(a) {
a = fround(a);
return sqrt(a);
}
return f;
}
var f = Module(this);
assertEquals(Math.sqrt(Math.fround(2.2)), f(2.2));
assertFalse(%IsAsmWasmCode(Module));
})();
(function TestMathAbsReturningFloatish() {
function Module(stdlib) {
"use asm";
var abs = stdlib.Math.abs;
var fround = stdlib.Math.fround;
function f(a) {
a = fround(a);
return abs(a);
}
return f;
}
var f = Module(this);
assertEquals(Math.fround(2.2), f(-2.2));
assertFalse(%IsAsmWasmCode(Module));
})();
(function TestMathMinReturningFloat() {
function Module(stdlib) {
"use asm";
var min = stdlib.Math.min;
var fround = stdlib.Math.fround;
function f(a) {
a = fround(a);
return min(a, a);
}
return f;
}
var f = Module(this);
assertEquals(Math.fround(2.2), f(2.2));
assertTrue(%IsAsmWasmCode(Module));
})();
(function TestMathMaxReturningFloat() {
function Module(stdlib) {
"use asm";
var max = stdlib.Math.max;
var fround = stdlib.Math.fround;
function f(a) {
a = fround(a);
return max(a, a);
}
return f;
}
var f = Module(this);
assertEquals(Math.fround(2.2), f(2.2));
assertTrue(%IsAsmWasmCode(Module));
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment