Commit aa912252 authored by jpp's avatar jpp Committed by Commit bot

V8. ASM-2-WASM. Migrates asm-wasm-builder to the new asm-typer.

BUG= https://bugs.chromium.org/p/v8/issues/detail?id=4203
TEST=mjsunit/wasm/*
LOG=N

Review-Url: https://codereview.chromium.org/2134333003
Cr-Commit-Position: refs/heads/master@{#37729}
parent 819fe046
......@@ -6,8 +6,8 @@
#include "src/api-natives.h"
#include "src/api.h"
#include "src/asmjs/asm-typer.h"
#include "src/asmjs/asm-wasm-builder.h"
#include "src/asmjs/typing-asm.h"
#include "src/assert-scope.h"
#include "src/ast/ast.h"
#include "src/ast/scopes.h"
......@@ -59,12 +59,8 @@ i::MaybeHandle<i::FixedArray> CompileModule(
MaybeHandle<FixedArray> AsmJs::ConvertAsmToWasm(ParseInfo* info) {
ErrorThrower thrower(info->isolate(), "Asm.js -> WebAssembly conversion");
AsmTyper typer(info->isolate(), info->zone(), *(info->script()),
info->literal());
typer.set_fixed_signature(true);
if (i::FLAG_enable_simd_asmjs) {
typer.set_allow_simd(true);
}
wasm::AsmTyper typer(info->isolate(), info->zone(), *(info->script()),
info->literal());
if (!typer.Validate()) {
DCHECK(!info->isolate()->has_pending_exception());
PrintF("Validation of asm.js module failed: %s", typer.error_message());
......
This diff is collapsed.
......@@ -22,6 +22,7 @@ namespace v8 {
namespace internal {
namespace wasm {
class AsmType;
class AsmTyperHarnessBuilder;
class AsmTyper final {
......@@ -313,6 +314,7 @@ class AsmTyper final {
bool stack_overflow_ = false;
ZoneMap<AstNode*, AsmType*> node_types_;
static const int kErrorMessageLimit = 100;
AsmType* fround_type_;
char error_message_[kErrorMessageLimit];
DISALLOW_IMPLICIT_CONSTRUCTORS(AsmTyper);
......
......@@ -173,6 +173,8 @@ class AsmFroundType final : public AsmFunctionType {
AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
bool CanBeInvokedWith(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
};
} // namespace
......@@ -181,6 +183,7 @@ AsmType* AsmType::FroundType(Zone* zone) {
return reinterpret_cast<AsmType*>(Fround);
}
// TODO(jpp): Remove this method.
AsmType* AsmFroundType::ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) {
if (args.size() != 1) {
......@@ -196,6 +199,21 @@ AsmType* AsmFroundType::ValidateCall(AsmType* return_type,
return AsmType::Float();
}
bool AsmFroundType::CanBeInvokedWith(AsmType* return_type,
const ZoneVector<AsmType*>& args) {
if (args.size() != 1) {
return false;
}
auto* arg = args[0];
if (!arg->IsA(AsmType::Floatish()) && !arg->IsA(AsmType::DoubleQ()) &&
!arg->IsA(AsmType::Signed()) && !arg->IsA(AsmType::Unsigned())) {
return false;
}
return true;
}
namespace {
class AsmMinMaxType final : public AsmFunctionType {
public:
......@@ -228,6 +246,26 @@ class AsmMinMaxType final : public AsmFunctionType {
return ReturnType();
}
bool CanBeInvokedWith(AsmType* return_type,
const ZoneVector<AsmType*>& args) override {
if (!ReturnType()->IsExactly(return_type)) {
return false;
}
if (args.size() < 2) {
return false;
}
auto* arg_type = Arguments()[0];
for (size_t ii = 0; ii < Arguments().size(); ++ii) {
if (!args[ii]->IsA(arg_type)) {
return false;
}
}
return true;
}
};
} // namespace
......@@ -249,6 +287,21 @@ AsmType* AsmFFIType::ValidateCall(AsmType* return_type,
return return_type;
}
bool AsmFFIType::CanBeInvokedWith(AsmType* return_type,
const ZoneVector<AsmType*>& args) {
if (return_type->IsExactly(AsmType::Float())) {
return false;
}
for (size_t ii = 0; ii < args.size(); ++ii) {
if (!args[ii]->IsA(AsmType::Extern())) {
return false;
}
}
return true;
}
AsmType* AsmFunctionType::ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) {
if (!return_type_->IsExactly(return_type)) {
......@@ -268,6 +321,25 @@ AsmType* AsmFunctionType::ValidateCall(AsmType* return_type,
return return_type_;
}
bool AsmFunctionType::CanBeInvokedWith(AsmType* return_type,
const ZoneVector<AsmType*>& args) {
if (!return_type_->IsExactly(return_type)) {
return false;
}
if (args_.size() != args.size()) {
return false;
}
for (size_t ii = 0; ii < args_.size(); ++ii) {
if (!args[ii]->IsA(args_[ii])) {
return false;
}
}
return true;
}
std::string AsmOverloadedFunctionType::Name() {
std::string ret;
......@@ -294,6 +366,17 @@ AsmType* AsmOverloadedFunctionType::ValidateCall(
return AsmType::None();
}
bool AsmOverloadedFunctionType::CanBeInvokedWith(
AsmType* return_type, const ZoneVector<AsmType*>& args) {
for (size_t ii = 0; ii < overloads_.size(); ++ii) {
if (overloads_[ii]->AsCallableType()->CanBeInvokedWith(return_type, args)) {
return true;
}
}
return false;
}
void AsmOverloadedFunctionType::AddOverload(AsmType* overload) {
DCHECK(overload->AsFunctionType() != nullptr);
overloads_.push_back(overload);
......@@ -314,6 +397,11 @@ AsmType* AsmFunctionTableType::ValidateCall(AsmType* return_type,
return signature_->AsCallableType()->ValidateCall(return_type, args);
}
bool AsmFunctionTableType::CanBeInvokedWith(AsmType* return_type,
const ZoneVector<AsmType*>& args) {
return signature_->AsCallableType()->CanBeInvokedWith(return_type, args);
}
} // namespace wasm
} // namespace internal
} // namespace v8
......@@ -110,6 +110,9 @@ class AsmCallableType : public ZoneObject {
virtual AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) = 0;
virtual bool CanBeInvokedWith(AsmType* return_type,
const ZoneVector<AsmType*>& args) = 0;
#define DECLARE_CAST(CamelName) \
virtual Asm##CamelName* As##CamelName() { return nullptr; }
FOR_EACH_ASM_CALLABLE_TYPE_LIST(DECLARE_CAST)
......@@ -136,6 +139,8 @@ class AsmFunctionType : public AsmCallableType {
AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
bool CanBeInvokedWith(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
protected:
AsmFunctionType(Zone* zone, AsmType* return_type)
......@@ -168,6 +173,8 @@ class AsmOverloadedFunctionType final : public AsmCallableType {
std::string Name() override;
AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
bool CanBeInvokedWith(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
ZoneVector<AsmType*> overloads_;
......@@ -181,6 +188,8 @@ class AsmFFIType final : public AsmCallableType {
std::string Name() override { return "Function"; }
AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
bool CanBeInvokedWith(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
private:
friend AsmType;
......@@ -198,6 +207,8 @@ class AsmFunctionTableType : public AsmCallableType {
AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
bool CanBeInvokedWith(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
size_t length() const { return length_; }
AsmType* signature() { return signature_; }
......
This diff is collapsed.
......@@ -6,7 +6,7 @@
#define V8_ASMJS_ASM_WASM_BUILDER_H_
#include "src/allocation.h"
#include "src/asmjs/typing-asm.h"
#include "src/asmjs/asm-typer.h"
#include "src/objects.h"
#include "src/wasm/encoder.h"
#include "src/zone.h"
......
......@@ -504,7 +504,6 @@ DEFINE_BOOL(wasm_loop_assignment_analysis, true,
"perform loop assignment analysis for WASM")
DEFINE_BOOL(validate_asm, false, "validate asm.js modules before compiling")
DEFINE_BOOL(enable_simd_asmjs, false, "enable SIMD.js in asm.js stdlib")
DEFINE_BOOL(dump_wasm_module, false, "dump WASM module bytes")
DEFINE_STRING(dump_wasm_module_path, NULL, "directory to dump wasm modules to")
......
......@@ -149,11 +149,8 @@ v8::internal::wasm::ZoneBuffer* TranslateAsmModule(
info->set_literal(
info->scope()->declarations()->at(0)->AsFunctionDeclaration()->fun());
v8::internal::AsmTyper typer(info->isolate(), info->zone(), *(info->script()),
info->literal());
if (i::FLAG_enable_simd_asmjs) {
typer.set_allow_simd(true);
}
v8::internal::wasm::AsmTyper typer(info->isolate(), info->zone(),
*(info->script()), info->literal());
if (!typer.Validate()) {
thrower->Error("Asm.js validation failed: %s", typer.error_message());
return nullptr;
......
......@@ -4,7 +4,7 @@
// Flags: --expose-wasm
function __f_61(stdlib, buffer) {
function __f_61(stdlib, foreign, buffer) {
"use asm";
var __v_14 = new stdlib.Float64Array(buffer);
function __f_74() {
......
......@@ -83,33 +83,34 @@
}
function caller() {
if (!deltaEqual(StdlibMathSqrt(123.0), 11.090536506409418)) return 0;
if (StdlibMathSqrt(fround(256.0)) != fround(16.0)) return 0;
if (StdlibMathCeil(123.7) != 124.0) return 0;
if (StdlibMathCeil(fround(123.7)) != fround(124.0)) return 0;
if (StdlibMathFloor(123.7) != 123.0) return 0;
if (StdlibMathFloor(fround(123.7)) != fround(123.0)) return 0;
if (StdlibMathAbs(-123.0) != 123.0) return 0;
if (StdlibMathAbs(fround(-123.0)) != fround(123.0)) return 0;
if (StdlibMathMin(123.4, 1236.4) != 123.4) return 0;
if (StdlibMathMin(fround(123.4),
fround(1236.4)) != fround(123.4)) return 0;
if (StdlibMathMax(123.4, 1236.4) != 1236.4) return 0;
if (StdlibMathMax(fround(123.4), fround(1236.4))
if (!(deltaEqual(+StdlibMathSqrt(123.0), 11.090536506409418)|0)) return 0;
if (fround(StdlibMathSqrt(fround(256.0))) != fround(16.0)) return 0;
if (+StdlibMathCeil(123.7) != 124.0) return 0;
if (fround(StdlibMathCeil(fround(123.7))) != fround(124.0)) return 0;
if (+StdlibMathFloor(123.7) != 123.0) return 0;
if (fround(StdlibMathFloor(fround(123.7))) != fround(123.0)) return 0;
if (+StdlibMathAbs(-123.0) != 123.0) return 0;
if (fround(StdlibMathAbs(fround(-123.0))) != fround(123.0)) return 0;
if (+StdlibMathMin(123.4, 1236.4) != 123.4) return 0;
if (fround(StdlibMathMin(fround(123.4),
fround(1236.4))) != fround(123.4)) return 0;
if (+StdlibMathMax(123.4, 1236.4) != 1236.4) return 0;
if (fround(StdlibMathMax(fround(123.4), fround(1236.4)))
!= fround(1236.4)) return 0;
if (!deltaEqual(StdlibMathAcos(0.1), 1.4706289056333368)) return 0;
if (!deltaEqual(StdlibMathAsin(0.2), 0.2013579207903308)) return 0;
if (!deltaEqual(StdlibMathAtan(0.2), 0.19739555984988078)) return 0;
if (!deltaEqual(StdlibMathCos(0.2), 0.9800665778412416)) return 0;
if (!deltaEqual(StdlibMathSin(0.2), 0.19866933079506122)) return 0;
if (!deltaEqual(StdlibMathTan(0.2), 0.20271003550867250)) return 0;
if (!deltaEqual(StdlibMathExp(0.2), 1.2214027581601699)) return 0;
if (!deltaEqual(StdlibMathLog(0.2), -1.6094379124341003)) return 0;
if (StdlibMathImul(6, 7) != 42) return 0;
if (!deltaEqual(StdlibMathAtan2(6.0, 7.0), 0.7086262721276703)) return 0;
if (StdlibMathPow(6.0, 7.0) != 279936.0) return 0;
if (!(deltaEqual(+StdlibMathAcos(0.1), 1.4706289056333368)|0)) return 0;
if (!(deltaEqual(+StdlibMathAsin(0.2), 0.2013579207903308)|0)) return 0;
if (!(deltaEqual(+StdlibMathAtan(0.2), 0.19739555984988078)|0)) return 0;
if (!(deltaEqual(+StdlibMathCos(0.2), 0.9800665778412416)|0)) return 0;
if (!(deltaEqual(+StdlibMathSin(0.2), 0.19866933079506122)|0)) return 0;
if (!(deltaEqual(+StdlibMathTan(0.2), 0.20271003550867250)|0)) return 0;
if (!(deltaEqual(+StdlibMathExp(0.2), 1.2214027581601699)|0)) return 0;
if (!(deltaEqual(+StdlibMathLog(0.2), -1.6094379124341003)|0)) return 0;
if ((StdlibMathImul(6, 7)|0) != 42) return 0;
if (!(deltaEqual(+StdlibMathAtan2(6.0, 7.0), 0.7086262721276703)|0))
return 0;
if (+StdlibMathPow(6.0, 7.0) != 279936.0) return 0;
return 1;
}
......
......@@ -11,7 +11,7 @@
function caller() {
var ret = 0;
var x = 7;
switch (x) {
switch (x|0) {
case 1: {
return 0;
}
......@@ -37,7 +37,7 @@
function caller() {
var ret = 0;
var x = 7;
switch (x) {
switch (x|0) {
case 1: return 0;
case 7: {
ret = 12;
......@@ -45,7 +45,7 @@
}
default: return 0;
}
switch (x) {
switch (x|0) {
case 1: return 0;
case 8: return 0;
default: ret = (ret + 11)|0;
......@@ -66,7 +66,7 @@
function caller() {
var x = 17;
var ret = 0;
switch (x) {
switch (x|0) {
case 17:
case 14: ret = 39;
case 1: ret = (ret + 3)|0;
......@@ -89,10 +89,10 @@
function caller() {
var x = 3;
var y = -13;
switch (x) {
switch (x|0) {
case 1: return 0;
case 3: {
switch (y) {
switch (y|0) {
case 2: return 0;
case -13: return 43;
default: return 0;
......
......@@ -43,9 +43,11 @@ function IntTest() {
function sum(a, b) {
a = a|0;
b = b|0;
var c = (b + 1)|0
var c = 0;
var d = 3.0;
var e = ~~d; // double conversion
var e = 0;
e = ~~d; // double conversion
c = (b + 1)|0
return (a + c + 1)|0;
}
......@@ -68,8 +70,9 @@ function Float64Test() {
}
function caller() {
var a = +sum(70.1,10.2);
var a = 0.0;
var ret = 0|0;
a = +sum(70.1,10.2);
if (a == 80.3) {
ret = 1|0;
} else {
......@@ -89,7 +92,8 @@ function BadModule() {
function caller(a, b) {
a = a|0;
b = b+0;
var c = (b + 1)|0
var c = 0;
c = (b + 1)|0
return (a + c + 1)|0;
}
......@@ -293,12 +297,12 @@ function TestBreakInNestedWhile() {
function caller() {
var x = 1.0;
var ret = 0;
while(x < 1.5) {
while(1)
break;
x = +(x + 0.25);
}
var ret = 0;
if (x == 1.5) {
ret = 9;
}
......@@ -405,7 +409,8 @@ function TestNot() {
"use asm";
function caller() {
var a = !(2 > 3);
var a = 0;
a = !(2 > 3);
return a | 0;
}
......@@ -886,7 +891,9 @@ function TestFunctionTableSingleFunction() {
}
function caller() {
return function_table[0&0]() | 0;
// TODO(jpp): the parser optimizes function_table[0&0] to function table[0].
var v = 0;
return function_table[v&0]() | 0;
}
var function_table = [dummy]
......@@ -911,8 +918,9 @@ function TestFunctionTableMultipleFunctions() {
}
function caller() {
if ((function_table[0&1](50)|0) == 51) {
if ((function_table[1&1](60)|0) == 62) {
var i = 0, j = 1;
if ((function_table[i&1](50)|0) == 51) {
if ((function_table[j&1](60)|0) == 62) {
return 73;
}
}
......@@ -1350,7 +1358,7 @@ assertWasm(1, TestXor);
"use asm";
function func() {
var a = 1;
return ((a * 3) + (4 * a)) | 0;
return (((a * 3)|0) + ((4 * a)|0)) | 0;
}
return {func: func};
}
......
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