Chromium Code Reviews| 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. |
|
bradnelson
2016/07/13 17:05:30
Where does this get hit?
John
2016/07/13 18:13:03
I did not investigate. I'll follow up shortly.
|
| + } |
| 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(); |