Commit 53b22823 authored by bradnelson's avatar bradnelson Committed by Commit bot

[wasm] asm.js: Work around parser converting !0 and !1 to boolean.

!0 -> true and !1 -> false etc in the parser.
This clashes with some of the typing logic in asm.js,
and can show up in some real programs in the wild (at least in past asm.js
versions).

BUG= https://bugs.chromium.org/p/v8/issues/detail?id=4203
R=aseemgarg@chromium.org,jpp@chromium.org

Review-Url: https://codereview.chromium.org/2372823004
Cr-Commit-Position: refs/heads/master@{#39798}
parent 7beb149f
......@@ -1664,6 +1664,12 @@ AsmType* AsmTyper::ValidateNumericLiteral(Literal* literal) {
return AsmType::Double();
}
// The parser collapses expressions like !0 and !123 to true/false.
// We therefore need to permit these as alternate versions of 0 / 1.
if (literal->raw_value()->IsTrue() || literal->raw_value()->IsFalse()) {
return AsmType::Int();
}
uint32_t value;
if (!literal->value()->ToUint32(&value)) {
int32_t value;
......
......@@ -589,7 +589,9 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
void VisitLiteral(Literal* expr) {
Handle<Object> value = expr->value();
if (!value->IsNumber() || (scope_ != kFuncScope && scope_ != kInitScope)) {
if (!(value->IsNumber() || expr->raw_value()->IsTrue() ||
expr->raw_value()->IsFalse()) ||
(scope_ != kFuncScope && scope_ != kInitScope)) {
return;
}
AsmType* type = typer_->TypeOf(expr);
......@@ -610,6 +612,18 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
int32_t i = static_cast<int32_t>(u);
byte code[] = {WASM_I32V(i)};
current_function_builder_->EmitCode(code, sizeof(code));
} else if (type->IsA(AsmType::Int())) {
// The parser can collapse !0, !1 etc to true / false.
// Allow these as int literals.
if (expr->raw_value()->IsTrue()) {
byte code[] = {WASM_I32V(1)};
current_function_builder_->EmitCode(code, sizeof(code));
} else if (expr->raw_value()->IsFalse()) {
byte code[] = {WASM_I32V(0)};
current_function_builder_->EmitCode(code, sizeof(code));
} else {
UNREACHABLE();
}
} else if (type->IsA(AsmType::Double())) {
double val = expr->raw_value()->AsNumber();
byte code[] = {WASM_F64(val)};
......
......@@ -1596,3 +1596,35 @@ function TestSingleFunctionModule() {
}
assertEquals(7, TestSingleFunctionModule()(3, 4));
function TestNotZero() {
"use asm";
function caller() {
if (!0) {
return 44;
} else {
return 55;
}
return 0;
}
return {caller: caller};
}
assertWasm(44, TestNotZero);
function TestNotOne() {
"use asm";
function caller() {
if (!1) {
return 44;
} else {
return 55;
}
return 0;
}
return {caller: caller};
}
assertWasm(55, TestNotOne);
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