| Index: src/asmjs/asm-wasm-builder.cc
|
| diff --git a/src/asmjs/asm-wasm-builder.cc b/src/asmjs/asm-wasm-builder.cc
|
| index c4b5c02d12874d09498ecf9097e01f03adf75cd2..83691efbf5460aad18dfecb18119904932f67bd6 100644
|
| --- a/src/asmjs/asm-wasm-builder.cc
|
| +++ b/src/asmjs/asm-wasm-builder.cc
|
| @@ -10,6 +10,7 @@
|
| #endif
|
| #include <math.h>
|
|
|
| +#include "src/asmjs/asm-types.h"
|
| #include "src/asmjs/asm-wasm-builder.h"
|
| #include "src/wasm/switch-logic.h"
|
| #include "src/wasm/wasm-macro-gen.h"
|
| @@ -18,7 +19,6 @@
|
| #include "src/ast/ast.h"
|
| #include "src/ast/scopes.h"
|
| #include "src/codegen.h"
|
| -#include "src/type-cache.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -59,7 +59,6 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| isolate_(isolate),
|
| zone_(zone),
|
| typer_(typer),
|
| - cache_(TypeCache::Get()),
|
| breakable_blocks_(zone),
|
| foreign_variables_(zone),
|
| init_function_index_(0),
|
| @@ -68,8 +67,7 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| function_tables_(base::HashMap::PointersMatch,
|
| ZoneHashMap::kDefaultHashMapCapacity,
|
| ZoneAllocationPolicy(zone)),
|
| - imported_function_table_(this),
|
| - bounds_(typer->bounds()) {
|
| + imported_function_table_(this) {
|
| InitializeAstVisitor(isolate);
|
| }
|
|
|
| @@ -359,12 +357,10 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| if (!clause->is_default()) {
|
| Literal* label = clause->label()->AsLiteral();
|
| Handle<Object> value = label->value();
|
| - DCHECK(value->IsNumber() &&
|
| - bounds_->get(label).upper->Is(cache_.kAsmSigned));
|
| int32_t label_value;
|
| - if (!value->ToInt32(&label_value)) {
|
| - UNREACHABLE();
|
| - }
|
| + bool label_is_i32 = value->ToInt32(&label_value);
|
| + DCHECK(value->IsNumber() && label_is_i32);
|
| + (void)label_is_i32;
|
| case_to_block[label_value] = i;
|
| cases.push_back(label_value);
|
| } else {
|
| @@ -459,15 +455,15 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| void VisitFunctionLiteral(FunctionLiteral* expr) override {
|
| Scope* scope = expr->scope();
|
| if (scope_ == kFuncScope) {
|
| - if (bounds_->get(expr).lower->IsFunction()) {
|
| + if (auto* func_type = typer_->TypeOf(expr)->AsFunctionType()) {
|
| // Build the signature for the function.
|
| - FunctionType* func_type = bounds_->get(expr).lower->AsFunction();
|
| - LocalType return_type = TypeFrom(func_type->Result());
|
| + LocalType return_type = TypeFrom(func_type->ReturnType());
|
| + const auto& arguments = func_type->Arguments();
|
| FunctionSig::Builder b(zone(), return_type == kAstStmt ? 0 : 1,
|
| - func_type->Arity());
|
| + arguments.size());
|
| if (return_type != kAstStmt) b.AddReturn(return_type);
|
| for (int i = 0; i < expr->parameter_count(); ++i) {
|
| - LocalType type = TypeFrom(func_type->Parameter(i));
|
| + LocalType type = TypeFrom(arguments[i]);
|
| DCHECK_NE(kAstStmt, type);
|
| b.AddParam(type);
|
| InsertParameter(scope->parameter(i), type, i);
|
| @@ -573,15 +569,17 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| if (!value->IsNumber() || (scope_ != kFuncScope && scope_ != kInitScope)) {
|
| return;
|
| }
|
| - Type* type = bounds_->get(expr).upper;
|
| - if (type->Is(cache_.kAsmSigned)) {
|
| + AsmType* type = typer_->TypeOf(expr);
|
| + DCHECK_NE(type, AsmType::None());
|
| +
|
| + if (type->IsA(AsmType::Signed())) {
|
| int32_t i = 0;
|
| if (!value->ToInt32(&i)) {
|
| UNREACHABLE();
|
| }
|
| byte code[] = {WASM_I32V(i)};
|
| current_function_builder_->EmitCode(code, sizeof(code));
|
| - } else if (type->Is(cache_.kAsmUnsigned) || type->Is(cache_.kAsmFixnum)) {
|
| + } else if (type->IsA(AsmType::Unsigned()) || type->IsA(AsmType::FixNum())) {
|
| uint32_t u = 0;
|
| if (!value->ToUint32(&u)) {
|
| UNREACHABLE();
|
| @@ -589,7 +587,7 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| int32_t i = static_cast<int32_t>(u);
|
| byte code[] = {WASM_I32V(i)};
|
| current_function_builder_->EmitCode(code, sizeof(code));
|
| - } else if (type->Is(cache_.kAsmDouble)) {
|
| + } else if (type->IsA(AsmType::Double())) {
|
| double val = expr->raw_value()->AsNumber();
|
| byte code[] = {WASM_F64(val)};
|
| current_function_builder_->EmitCode(code, sizeof(code));
|
| @@ -635,16 +633,18 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| }
|
|
|
| void AddFunctionTable(VariableProxy* table, ArrayLiteral* funcs) {
|
| - FunctionType* func_type =
|
| - bounds_->get(funcs).lower->AsArray()->Element()->AsFunction();
|
| - LocalType return_type = TypeFrom(func_type->Result());
|
| + auto* func_tbl_type = typer_->TypeOf(funcs)->AsFunctionTableType();
|
| + DCHECK_NOT_NULL(func_tbl_type);
|
| + auto* func_type = func_tbl_type->signature()->AsFunctionType();
|
| + const auto& arguments = func_type->Arguments();
|
| + LocalType return_type = TypeFrom(func_type->ReturnType());
|
| FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1,
|
| - func_type->Arity());
|
| + arguments.size());
|
| if (return_type != kAstStmt) {
|
| - sig.AddReturn(static_cast<LocalType>(return_type));
|
| + sig.AddReturn(return_type);
|
| }
|
| - for (int i = 0; i < func_type->Arity(); ++i) {
|
| - sig.AddParam(TypeFrom(func_type->Parameter(i)));
|
| + for (auto* arg : arguments) {
|
| + sig.AddParam(TypeFrom(arg));
|
| }
|
| uint32_t signature_index = builder_->AddSignature(sig.Build());
|
| InsertFunctionTable(table->var(), next_table_index_, signature_index);
|
| @@ -805,8 +805,8 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| if (target_prop != nullptr) {
|
| // Left hand side is a property access, i.e. the asm.js heap.
|
| if (TypeOf(expr->value()) == kAstF64 && expr->target()->IsProperty() &&
|
| - bounds_->get(expr->target()->AsProperty()->obj())
|
| - .lower->Is(cache_.kFloat32Array)) {
|
| + typer_->TypeOf(expr->target()->AsProperty()->obj())
|
| + ->IsA(AsmType::Float32Array())) {
|
| current_function_builder_->Emit(kExprF32ConvertF64);
|
| }
|
| WasmOpcode opcode;
|
| @@ -846,7 +846,7 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| if (vp != nullptr && vp->var()->IsParameter() &&
|
| vp->var()->index() == 1) {
|
| VariableProxy* target = expr->target()->AsVariableProxy();
|
| - if (bounds_->get(target).lower->Is(Type::Function())) {
|
| + if (typer_->TypeOf(target)->AsFFIType() != nullptr) {
|
| const AstRawString* name =
|
| prop->key()->AsLiteral()->AsRawPropertyName();
|
| imported_function_table_.AddImport(
|
| @@ -859,7 +859,10 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| }
|
| ArrayLiteral* funcs = expr->value()->AsArrayLiteral();
|
| if (funcs != nullptr &&
|
| - bounds_->get(funcs).lower->AsArray()->Element()->IsFunction()) {
|
| + typer_->TypeOf(funcs)
|
| + ->AsFunctionTableType()
|
| + ->signature()
|
| + ->AsFunctionType()) {
|
| VariableProxy* target = expr->target()->AsVariableProxy();
|
| DCHECK_NOT_NULL(target);
|
| AddFunctionTable(target, funcs);
|
| @@ -905,34 +908,33 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
|
|
| void VisitPropertyAndEmitIndex(Property* expr, MachineType* mtype) {
|
| Expression* obj = expr->obj();
|
| - DCHECK_EQ(bounds_->get(obj).lower, bounds_->get(obj).upper);
|
| - Type* type = bounds_->get(obj).lower;
|
| + AsmType* type = typer_->TypeOf(obj);
|
| int size;
|
| - if (type->Is(cache_.kUint8Array)) {
|
| + if (type->IsA(AsmType::Uint8Array())) {
|
| *mtype = MachineType::Uint8();
|
| size = 1;
|
| - } else if (type->Is(cache_.kInt8Array)) {
|
| + } else if (type->IsA(AsmType::Int8Array())) {
|
| *mtype = MachineType::Int8();
|
| size = 1;
|
| - } else if (type->Is(cache_.kUint16Array)) {
|
| + } else if (type->IsA(AsmType::Uint16Array())) {
|
| *mtype = MachineType::Uint16();
|
| size = 2;
|
| - } else if (type->Is(cache_.kInt16Array)) {
|
| + } else if (type->IsA(AsmType::Int16Array())) {
|
| *mtype = MachineType::Int16();
|
| size = 2;
|
| - } else if (type->Is(cache_.kUint32Array)) {
|
| + } else if (type->IsA(AsmType::Uint32Array())) {
|
| *mtype = MachineType::Uint32();
|
| size = 4;
|
| - } else if (type->Is(cache_.kInt32Array)) {
|
| + } else if (type->IsA(AsmType::Int32Array())) {
|
| *mtype = MachineType::Int32();
|
| size = 4;
|
| - } else if (type->Is(cache_.kUint32Array)) {
|
| + } else if (type->IsA(AsmType::Uint32Array())) {
|
| *mtype = MachineType::Uint32();
|
| size = 4;
|
| - } else if (type->Is(cache_.kFloat32Array)) {
|
| + } else if (type->IsA(AsmType::Float32Array())) {
|
| *mtype = MachineType::Float32();
|
| size = 4;
|
| - } else if (type->Is(cache_.kFloat64Array)) {
|
| + } else if (type->IsA(AsmType::Float64Array())) {
|
| *mtype = MachineType::Float64();
|
| size = 8;
|
| } else {
|
| @@ -1228,7 +1230,8 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| }
|
| }
|
| VisitCallArgs(call);
|
| - switch (TypeIndexOf(args->at(0))) {
|
| + static const bool kDontIgnoreSign = false;
|
| + switch (TypeIndexOf(args->at(0), kDontIgnoreSign)) {
|
| case kInt32:
|
| case kFixnum:
|
| current_function_builder_->Emit(kExprF32SConvertI32);
|
| @@ -1275,8 +1278,8 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| }
|
| uint32_t index;
|
| VariableProxy* vp = expr->expression()->AsVariableProxy();
|
| - if (vp != nullptr &&
|
| - Type::Any()->Is(bounds_->get(vp).lower->AsFunction()->Result())) {
|
| + DCHECK_NOT_NULL(vp);
|
| + if (typer_->TypeOf(vp)->AsFFIType() != nullptr) {
|
| LocalType return_type = TypeOf(expr);
|
| ZoneList<Expression*>* args = expr->arguments();
|
| FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1,
|
| @@ -1479,9 +1482,10 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
|
|
| void VisitBinaryOperation(BinaryOperation* expr) override {
|
| ConvertOperation convertOperation = MatchBinaryOperation(expr);
|
| + static const bool kDontIgnoreSign = false;
|
| if (convertOperation == kToDouble) {
|
| RECURSE(Visit(expr->left()));
|
| - TypeIndex type = TypeIndexOf(expr->left());
|
| + TypeIndex type = TypeIndexOf(expr->left(), kDontIgnoreSign);
|
| if (type == kInt32 || type == kFixnum) {
|
| current_function_builder_->Emit(kExprF64SConvertI32);
|
| } else if (type == kUint32) {
|
| @@ -1493,7 +1497,7 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| }
|
| } else if (convertOperation == kToInt) {
|
| RECURSE(Visit(GetLeft(expr)));
|
| - TypeIndex type = TypeIndexOf(GetLeft(expr));
|
| + TypeIndex type = TypeIndexOf(GetLeft(expr), kDontIgnoreSign);
|
| if (type == kFloat32) {
|
| current_function_builder_->Emit(kExprI32AsmjsSConvertF32);
|
| } else if (type == kFloat64) {
|
| @@ -1583,8 +1587,8 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| };
|
|
|
| TypeIndex TypeIndexOf(Expression* left, Expression* right, bool ignore_sign) {
|
| - TypeIndex left_index = TypeIndexOf(left);
|
| - TypeIndex right_index = TypeIndexOf(right);
|
| + TypeIndex left_index = TypeIndexOf(left, ignore_sign);
|
| + TypeIndex right_index = TypeIndexOf(right, ignore_sign);
|
| if (left_index == kFixnum) {
|
| left_index = right_index;
|
| }
|
| @@ -1595,30 +1599,43 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| left_index = kInt32;
|
| right_index = kInt32;
|
| }
|
| - DCHECK((left_index == right_index) ||
|
| - (ignore_sign && (left_index <= 1) && (right_index <= 1)));
|
| + if (left_index != right_index) {
|
| + DCHECK(ignore_sign && (left_index <= 1) && (right_index <= 1));
|
| + }
|
| return left_index;
|
| }
|
|
|
| - TypeIndex TypeIndexOf(Expression* expr) {
|
| - DCHECK_EQ(bounds_->get(expr).lower, bounds_->get(expr).upper);
|
| - Type* type = bounds_->get(expr).lower;
|
| - if (type->Is(cache_.kAsmFixnum)) {
|
| + TypeIndex TypeIndexOf(Expression* expr, bool ignore_sign) {
|
| + AsmType* type = typer_->TypeOf(expr);
|
| + if (type->IsA(AsmType::FixNum())) {
|
| return kFixnum;
|
| - } else if (type->Is(cache_.kAsmSigned)) {
|
| + }
|
| +
|
| + if (type->IsA(AsmType::Signed())) {
|
| return kInt32;
|
| - } else if (type->Is(cache_.kAsmUnsigned)) {
|
| + }
|
| +
|
| + if (type->IsA(AsmType::Unsigned())) {
|
| return kUint32;
|
| - } else if (type->Is(cache_.kAsmInt)) {
|
| + }
|
| +
|
| + if (type->IsA(AsmType::Intish())) {
|
| + if (!ignore_sign) {
|
| + // TODO(jpp): log a warning and move on.
|
| + }
|
| return kInt32;
|
| - } else if (type->Is(cache_.kAsmFloat)) {
|
| + }
|
| +
|
| + if (type->IsA(AsmType::Floatish())) {
|
| return kFloat32;
|
| - } else if (type->Is(cache_.kAsmDouble)) {
|
| + }
|
| +
|
| + if (type->IsA(AsmType::DoubleQ())) {
|
| return kFloat64;
|
| - } else {
|
| - UNREACHABLE();
|
| - return kInt32;
|
| }
|
| +
|
| + UNREACHABLE();
|
| + return kInt32;
|
| }
|
|
|
| #undef CASE
|
| @@ -1721,21 +1738,22 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| return (reinterpret_cast<IndexContainer*>(entry->value))->index;
|
| }
|
|
|
| - LocalType TypeOf(Expression* expr) {
|
| - DCHECK_EQ(bounds_->get(expr).lower, bounds_->get(expr).upper);
|
| - return TypeFrom(bounds_->get(expr).lower);
|
| - }
|
| + LocalType TypeOf(Expression* expr) { return TypeFrom(typer_->TypeOf(expr)); }
|
|
|
| - LocalType TypeFrom(Type* type) {
|
| - if (type->Is(cache_.kAsmInt)) {
|
| + LocalType TypeFrom(AsmType* type) {
|
| + if (type->IsA(AsmType::Intish())) {
|
| return kAstI32;
|
| - } else if (type->Is(cache_.kAsmFloat)) {
|
| + }
|
| +
|
| + if (type->IsA(AsmType::Floatish())) {
|
| return kAstF32;
|
| - } else if (type->Is(cache_.kAsmDouble)) {
|
| + }
|
| +
|
| + if (type->IsA(AsmType::DoubleQ())) {
|
| return kAstF64;
|
| - } else {
|
| - return kAstStmt;
|
| }
|
| +
|
| + return kAstStmt;
|
| }
|
|
|
| Zone* zone() { return zone_; }
|
| @@ -1750,7 +1768,6 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| Isolate* isolate_;
|
| Zone* zone_;
|
| AsmTyper* typer_;
|
| - TypeCache const& cache_;
|
| ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
|
| ZoneVector<ForeignVariable> foreign_variables_;
|
| uint32_t init_function_index_;
|
| @@ -1758,7 +1775,6 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| uint32_t next_table_index_;
|
| ZoneHashMap function_tables_;
|
| ImportedFunctionTable imported_function_table_;
|
| - const AstTypeBounds* bounds_;
|
|
|
| DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
|
|
|
|
|