Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: src/asmjs/asm-wasm-builder.cc

Issue 2594993002: [wasm] Rename wasm::LocalType to wasm::ValueType and kAst* to kWasm* (Closed)
Patch Set: Fix inspector tests Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/compiler/wasm-compiler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 // Required to get M_E etc. in MSVC. 7 // Required to get M_E etc. in MSVC.
8 #if defined(_WIN32) 8 #if defined(_WIN32)
9 #define _USE_MATH_DEFINES 9 #define _USE_MATH_DEFINES
10 #endif 10 #endif
(...skipping 24 matching lines...) Expand all
35 call; \ 35 call; \
36 if (HasStackOverflow()) return; \ 36 if (HasStackOverflow()) return; \
37 } while (false) 37 } while (false)
38 38
39 enum AsmScope { kModuleScope, kInitScope, kFuncScope, kExportScope }; 39 enum AsmScope { kModuleScope, kInitScope, kFuncScope, kExportScope };
40 enum ValueFate { kDrop, kLeaveOnStack }; 40 enum ValueFate { kDrop, kLeaveOnStack };
41 41
42 struct ForeignVariable { 42 struct ForeignVariable {
43 Handle<Name> name; 43 Handle<Name> name;
44 Variable* var; 44 Variable* var;
45 LocalType type; 45 ValueType type;
46 }; 46 };
47 47
48 class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> { 48 class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
49 public: 49 public:
50 AsmWasmBuilderImpl(Isolate* isolate, Zone* zone, CompilationInfo* info, 50 AsmWasmBuilderImpl(Isolate* isolate, Zone* zone, CompilationInfo* info,
51 AstValueFactory* ast_value_factory, Handle<Script> script, 51 AstValueFactory* ast_value_factory, Handle<Script> script,
52 FunctionLiteral* literal, AsmTyper* typer) 52 FunctionLiteral* literal, AsmTyper* typer)
53 : local_variables_(ZoneHashMap::kDefaultHashMapCapacity, 53 : local_variables_(ZoneHashMap::kDefaultHashMapCapacity,
54 ZoneAllocationPolicy(zone)), 54 ZoneAllocationPolicy(zone)),
55 functions_(ZoneHashMap::kDefaultHashMapCapacity, 55 functions_(ZoneHashMap::kDefaultHashMapCapacity,
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 509
510 void VisitDebuggerStatement(DebuggerStatement* stmt) { UNREACHABLE(); } 510 void VisitDebuggerStatement(DebuggerStatement* stmt) { UNREACHABLE(); }
511 511
512 void VisitFunctionLiteral(FunctionLiteral* expr) { 512 void VisitFunctionLiteral(FunctionLiteral* expr) {
513 DeclarationScope* scope = expr->scope(); 513 DeclarationScope* scope = expr->scope();
514 if (scope_ == kFuncScope) { 514 if (scope_ == kFuncScope) {
515 if (auto* func_type = typer_->TypeOf(expr)->AsFunctionType()) { 515 if (auto* func_type = typer_->TypeOf(expr)->AsFunctionType()) {
516 // Add the parameters for the function. 516 // Add the parameters for the function.
517 const auto& arguments = func_type->Arguments(); 517 const auto& arguments = func_type->Arguments();
518 for (int i = 0; i < expr->parameter_count(); ++i) { 518 for (int i = 0; i < expr->parameter_count(); ++i) {
519 LocalType type = TypeFrom(arguments[i]); 519 ValueType type = TypeFrom(arguments[i]);
520 DCHECK_NE(kAstStmt, type); 520 DCHECK_NE(kWasmStmt, type);
521 InsertParameter(scope->parameter(i), type, i); 521 InsertParameter(scope->parameter(i), type, i);
522 } 522 }
523 } else { 523 } else {
524 UNREACHABLE(); 524 UNREACHABLE();
525 } 525 }
526 } 526 }
527 RECURSE(VisitDeclarations(scope->declarations())); 527 RECURSE(VisitDeclarations(scope->declarations()));
528 if (typer_failed_) return; 528 if (typer_failed_) return;
529 RECURSE(VisitStatements(expr->body())); 529 RECURSE(VisitStatements(expr->body()));
530 } 530 }
531 531
532 void VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { 532 void VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
533 UNREACHABLE(); 533 UNREACHABLE();
534 } 534 }
535 535
536 void VisitConditional(Conditional* expr) { 536 void VisitConditional(Conditional* expr) {
537 DCHECK_EQ(kFuncScope, scope_); 537 DCHECK_EQ(kFuncScope, scope_);
538 RECURSE(Visit(expr->condition())); 538 RECURSE(Visit(expr->condition()));
539 // WASM ifs come with implicit blocks for both arms. 539 // WASM ifs come with implicit blocks for both arms.
540 breakable_blocks_.push_back(std::make_pair(nullptr, false)); 540 breakable_blocks_.push_back(std::make_pair(nullptr, false));
541 LocalTypeCode type; 541 ValueTypeCode type;
542 switch (TypeOf(expr)) { 542 switch (TypeOf(expr)) {
543 case kAstI32: 543 case kWasmI32:
544 type = kLocalI32; 544 type = kLocalI32;
545 break; 545 break;
546 case kAstI64: 546 case kWasmI64:
547 type = kLocalI64; 547 type = kLocalI64;
548 break; 548 break;
549 case kAstF32: 549 case kWasmF32:
550 type = kLocalF32; 550 type = kLocalF32;
551 break; 551 break;
552 case kAstF64: 552 case kWasmF64:
553 type = kLocalF64; 553 type = kLocalF64;
554 break; 554 break;
555 default: 555 default:
556 UNREACHABLE(); 556 UNREACHABLE();
557 } 557 }
558 current_function_builder_->EmitWithU8(kExprIf, type); 558 current_function_builder_->EmitWithU8(kExprIf, type);
559 RECURSE(Visit(expr->then_expression())); 559 RECURSE(Visit(expr->then_expression()));
560 current_function_builder_->Emit(kExprElse); 560 current_function_builder_->Emit(kExprElse);
561 RECURSE(Visit(expr->else_expression())); 561 RECURSE(Visit(expr->else_expression()));
562 current_function_builder_->Emit(kExprEnd); 562 current_function_builder_->Emit(kExprEnd);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 current_function_builder_->EmitCode(code, sizeof(code)); 614 current_function_builder_->EmitCode(code, sizeof(code));
615 return true; 615 return true;
616 } 616 }
617 617
618 void VisitVariableProxy(VariableProxy* expr) { 618 void VisitVariableProxy(VariableProxy* expr) {
619 if (scope_ == kFuncScope || scope_ == kInitScope) { 619 if (scope_ == kFuncScope || scope_ == kInitScope) {
620 Variable* var = expr->var(); 620 Variable* var = expr->var();
621 if (VisitStdlibConstant(var)) { 621 if (VisitStdlibConstant(var)) {
622 return; 622 return;
623 } 623 }
624 LocalType var_type = TypeOf(expr); 624 ValueType var_type = TypeOf(expr);
625 DCHECK_NE(kAstStmt, var_type); 625 DCHECK_NE(kWasmStmt, var_type);
626 if (var->IsContextSlot()) { 626 if (var->IsContextSlot()) {
627 current_function_builder_->EmitWithVarInt( 627 current_function_builder_->EmitWithVarInt(
628 kExprGetGlobal, LookupOrInsertGlobal(var, var_type)); 628 kExprGetGlobal, LookupOrInsertGlobal(var, var_type));
629 } else { 629 } else {
630 current_function_builder_->EmitGetLocal( 630 current_function_builder_->EmitGetLocal(
631 LookupOrInsertLocal(var, var_type)); 631 LookupOrInsertLocal(var, var_type));
632 } 632 }
633 } else if (scope_ == kExportScope) { 633 } else if (scope_ == kExportScope) {
634 Variable* var = expr->var(); 634 Variable* var = expr->var();
635 DCHECK(var->is_function()); 635 DCHECK(var->is_function());
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 FunctionTableIndices* indices = LookupFunctionTable(table->var()); 748 FunctionTableIndices* indices = LookupFunctionTable(table->var());
749 if (indices != nullptr) { 749 if (indices != nullptr) {
750 // Already setup. 750 // Already setup.
751 return indices; 751 return indices;
752 } 752 }
753 indices = new (zone()) FunctionTableIndices(); 753 indices = new (zone()) FunctionTableIndices();
754 auto* func_type = typer_->TypeOf(p)->AsFunctionType(); 754 auto* func_type = typer_->TypeOf(p)->AsFunctionType();
755 auto* func_table_type = typer_->TypeOf(p->obj()->AsVariableProxy()->var()) 755 auto* func_table_type = typer_->TypeOf(p->obj()->AsVariableProxy()->var())
756 ->AsFunctionTableType(); 756 ->AsFunctionTableType();
757 const auto& arguments = func_type->Arguments(); 757 const auto& arguments = func_type->Arguments();
758 LocalType return_type = TypeFrom(func_type->ReturnType()); 758 ValueType return_type = TypeFrom(func_type->ReturnType());
759 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1, 759 FunctionSig::Builder sig(zone(), return_type == kWasmStmt ? 0 : 1,
760 arguments.size()); 760 arguments.size());
761 if (return_type != kAstStmt) { 761 if (return_type != kWasmStmt) {
762 sig.AddReturn(return_type); 762 sig.AddReturn(return_type);
763 } 763 }
764 for (auto* arg : arguments) { 764 for (auto* arg : arguments) {
765 sig.AddParam(TypeFrom(arg)); 765 sig.AddParam(TypeFrom(arg));
766 } 766 }
767 uint32_t signature_index = builder_->AddSignature(sig.Build()); 767 uint32_t signature_index = builder_->AddSignature(sig.Build());
768 indices->start_index = builder_->AllocateIndirectFunctions( 768 indices->start_index = builder_->AllocateIndirectFunctions(
769 static_cast<uint32_t>(func_table_type->length())); 769 static_cast<uint32_t>(func_table_type->length()));
770 indices->signature_index = signature_index; 770 indices->signature_index = signature_index;
771 ZoneHashMap::Entry* entry = function_tables_.LookupOrInsert( 771 ZoneHashMap::Entry* entry = function_tables_.LookupOrInsert(
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 } 917 }
918 RECURSE(Visit(value)); 918 RECURSE(Visit(value));
919 } 919 }
920 920
921 void EmitAssignment(Assignment* expr, AsmType* type, ValueFate fate) { 921 void EmitAssignment(Assignment* expr, AsmType* type, ValueFate fate) {
922 // Match the left hand side of the assignment. 922 // Match the left hand side of the assignment.
923 VariableProxy* target_var = expr->target()->AsVariableProxy(); 923 VariableProxy* target_var = expr->target()->AsVariableProxy();
924 if (target_var != nullptr) { 924 if (target_var != nullptr) {
925 // Left hand side is a local or a global variable. 925 // Left hand side is a local or a global variable.
926 Variable* var = target_var->var(); 926 Variable* var = target_var->var();
927 LocalType var_type = TypeOf(expr); 927 ValueType var_type = TypeOf(expr);
928 DCHECK_NE(kAstStmt, var_type); 928 DCHECK_NE(kWasmStmt, var_type);
929 if (var->IsContextSlot()) { 929 if (var->IsContextSlot()) {
930 uint32_t index = LookupOrInsertGlobal(var, var_type); 930 uint32_t index = LookupOrInsertGlobal(var, var_type);
931 current_function_builder_->EmitWithVarInt(kExprSetGlobal, index); 931 current_function_builder_->EmitWithVarInt(kExprSetGlobal, index);
932 if (fate == kLeaveOnStack) { 932 if (fate == kLeaveOnStack) {
933 current_function_builder_->EmitWithVarInt(kExprGetGlobal, index); 933 current_function_builder_->EmitWithVarInt(kExprGetGlobal, index);
934 } 934 }
935 } else { 935 } else {
936 if (fate == kDrop) { 936 if (fate == kDrop) {
937 current_function_builder_->EmitSetLocal( 937 current_function_builder_->EmitSetLocal(
938 LookupOrInsertLocal(var, var_type)); 938 LookupOrInsertLocal(var, var_type));
939 } else { 939 } else {
940 current_function_builder_->EmitTeeLocal( 940 current_function_builder_->EmitTeeLocal(
941 LookupOrInsertLocal(var, var_type)); 941 LookupOrInsertLocal(var, var_type));
942 } 942 }
943 } 943 }
944 } 944 }
945 945
946 Property* target_prop = expr->target()->AsProperty(); 946 Property* target_prop = expr->target()->AsProperty();
947 if (target_prop != nullptr) { 947 if (target_prop != nullptr) {
948 // Left hand side is a property access, i.e. the asm.js heap. 948 // Left hand side is a property access, i.e. the asm.js heap.
949 if (TypeOf(expr->value()) == kAstF64 && expr->target()->IsProperty() && 949 if (TypeOf(expr->value()) == kWasmF64 && expr->target()->IsProperty() &&
950 typer_->TypeOf(expr->target()->AsProperty()->obj()) 950 typer_->TypeOf(expr->target()->AsProperty()->obj())
951 ->IsA(AsmType::Float32Array())) { 951 ->IsA(AsmType::Float32Array())) {
952 current_function_builder_->Emit(kExprF32ConvertF64); 952 current_function_builder_->Emit(kExprF32ConvertF64);
953 } 953 }
954 // Note that unlike StoreMem, AsmjsStoreMem ignores out-of-bounds writes. 954 // Note that unlike StoreMem, AsmjsStoreMem ignores out-of-bounds writes.
955 WasmOpcode opcode; 955 WasmOpcode opcode;
956 if (type == AsmType::Int8Array()) { 956 if (type == AsmType::Int8Array()) {
957 opcode = kExprI32AsmjsStoreMem8; 957 opcode = kExprI32AsmjsStoreMem8;
958 } else if (type == AsmType::Uint8Array()) { 958 } else if (type == AsmType::Uint8Array()) {
959 opcode = kExprI32AsmjsStoreMem8; 959 opcode = kExprI32AsmjsStoreMem8;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 void VisitForeignVariable(bool is_float, Variable* var, Property* expr) { 1047 void VisitForeignVariable(bool is_float, Variable* var, Property* expr) {
1048 DCHECK(expr->obj()->AsVariableProxy()); 1048 DCHECK(expr->obj()->AsVariableProxy());
1049 DCHECK(VariableLocation::PARAMETER == 1049 DCHECK(VariableLocation::PARAMETER ==
1050 expr->obj()->AsVariableProxy()->var()->location()); 1050 expr->obj()->AsVariableProxy()->var()->location());
1051 DCHECK_EQ(1, expr->obj()->AsVariableProxy()->var()->index()); 1051 DCHECK_EQ(1, expr->obj()->AsVariableProxy()->var()->index());
1052 Literal* key_literal = expr->key()->AsLiteral(); 1052 Literal* key_literal = expr->key()->AsLiteral();
1053 DCHECK_NOT_NULL(key_literal); 1053 DCHECK_NOT_NULL(key_literal);
1054 if (!key_literal->value().is_null()) { 1054 if (!key_literal->value().is_null()) {
1055 Handle<Name> name = 1055 Handle<Name> name =
1056 Object::ToName(isolate_, key_literal->value()).ToHandleChecked(); 1056 Object::ToName(isolate_, key_literal->value()).ToHandleChecked();
1057 LocalType type = is_float ? kAstF64 : kAstI32; 1057 ValueType type = is_float ? kWasmF64 : kWasmI32;
1058 foreign_variables_.push_back({name, var, type}); 1058 foreign_variables_.push_back({name, var, type});
1059 } 1059 }
1060 } 1060 }
1061 1061
1062 void VisitPropertyAndEmitIndex(Property* expr, AsmType** atype) { 1062 void VisitPropertyAndEmitIndex(Property* expr, AsmType** atype) {
1063 Expression* obj = expr->obj(); 1063 Expression* obj = expr->obj();
1064 *atype = typer_->TypeOf(obj); 1064 *atype = typer_->TypeOf(obj);
1065 int size = (*atype)->ElementSizeInBytes(); 1065 int size = (*atype)->ElementSizeInBytes();
1066 if (size == 1) { 1066 if (size == 1) {
1067 // Allow more general expression in byte arrays than the spec 1067 // Allow more general expression in byte arrays than the spec
1068 // strictly permits. 1068 // strictly permits.
1069 // Early versions of Emscripten emit HEAP8[HEAP32[..]|0] in 1069 // Early versions of Emscripten emit HEAP8[HEAP32[..]|0] in
1070 // places that strictly should be HEAP8[HEAP32[..]>>0]. 1070 // places that strictly should be HEAP8[HEAP32[..]>>0].
1071 RECURSE(Visit(expr->key())); 1071 RECURSE(Visit(expr->key()));
1072 return; 1072 return;
1073 } 1073 }
1074 1074
1075 Literal* value = expr->key()->AsLiteral(); 1075 Literal* value = expr->key()->AsLiteral();
1076 if (value) { 1076 if (value) {
1077 DCHECK(value->raw_value()->IsNumber()); 1077 DCHECK(value->raw_value()->IsNumber());
1078 DCHECK_EQ(kAstI32, TypeOf(value)); 1078 DCHECK_EQ(kWasmI32, TypeOf(value));
1079 int32_t val = static_cast<int32_t>(value->raw_value()->AsNumber()); 1079 int32_t val = static_cast<int32_t>(value->raw_value()->AsNumber());
1080 // TODO(titzer): handle overflow here. 1080 // TODO(titzer): handle overflow here.
1081 current_function_builder_->EmitI32Const(val * size); 1081 current_function_builder_->EmitI32Const(val * size);
1082 return; 1082 return;
1083 } 1083 }
1084 BinaryOperation* binop = expr->key()->AsBinaryOperation(); 1084 BinaryOperation* binop = expr->key()->AsBinaryOperation();
1085 if (binop) { 1085 if (binop) {
1086 DCHECK_EQ(Token::SAR, binop->op()); 1086 DCHECK_EQ(Token::SAR, binop->op());
1087 DCHECK(binop->right()->AsLiteral()->raw_value()->IsNumber()); 1087 DCHECK(binop->right()->AsLiteral()->raw_value()->IsNumber());
1088 DCHECK(kAstI32 == TypeOf(binop->right()->AsLiteral())); 1088 DCHECK(kWasmI32 == TypeOf(binop->right()->AsLiteral()));
1089 DCHECK_EQ(size, 1089 DCHECK_EQ(size,
1090 1 << static_cast<int>( 1090 1 << static_cast<int>(
1091 binop->right()->AsLiteral()->raw_value()->AsNumber())); 1091 binop->right()->AsLiteral()->raw_value()->AsNumber()));
1092 // Mask bottom bits to match asm.js behavior. 1092 // Mask bottom bits to match asm.js behavior.
1093 byte mask = static_cast<byte>(~(size - 1)); 1093 byte mask = static_cast<byte>(~(size - 1));
1094 RECURSE(Visit(binop->left())); 1094 RECURSE(Visit(binop->left()));
1095 current_function_builder_->EmitWithU8(kExprI8Const, mask); 1095 current_function_builder_->EmitWithU8(kExprI8Const, mask);
1096 current_function_builder_->Emit(kExprI32And); 1096 current_function_builder_->Emit(kExprI32And);
1097 return; 1097 return;
1098 } 1098 }
(...skipping 25 matching lines...) Expand all
1124 } 1124 }
1125 1125
1126 current_function_builder_->Emit(opcode); 1126 current_function_builder_->Emit(opcode);
1127 } 1127 }
1128 1128
1129 bool VisitStdlibFunction(Call* call, VariableProxy* expr) { 1129 bool VisitStdlibFunction(Call* call, VariableProxy* expr) {
1130 Variable* var = expr->var(); 1130 Variable* var = expr->var();
1131 AsmTyper::StandardMember standard_object = 1131 AsmTyper::StandardMember standard_object =
1132 typer_->VariableAsStandardMember(var); 1132 typer_->VariableAsStandardMember(var);
1133 ZoneList<Expression*>* args = call->arguments(); 1133 ZoneList<Expression*>* args = call->arguments();
1134 LocalType call_type = TypeOf(call); 1134 ValueType call_type = TypeOf(call);
1135 1135
1136 switch (standard_object) { 1136 switch (standard_object) {
1137 case AsmTyper::kNone: { 1137 case AsmTyper::kNone: {
1138 return false; 1138 return false;
1139 } 1139 }
1140 case AsmTyper::kMathAcos: { 1140 case AsmTyper::kMathAcos: {
1141 VisitCallArgs(call); 1141 VisitCallArgs(call);
1142 DCHECK_EQ(kAstF64, call_type); 1142 DCHECK_EQ(kWasmF64, call_type);
1143 current_function_builder_->Emit(kExprF64Acos); 1143 current_function_builder_->Emit(kExprF64Acos);
1144 break; 1144 break;
1145 } 1145 }
1146 case AsmTyper::kMathAsin: { 1146 case AsmTyper::kMathAsin: {
1147 VisitCallArgs(call); 1147 VisitCallArgs(call);
1148 DCHECK_EQ(kAstF64, call_type); 1148 DCHECK_EQ(kWasmF64, call_type);
1149 current_function_builder_->Emit(kExprF64Asin); 1149 current_function_builder_->Emit(kExprF64Asin);
1150 break; 1150 break;
1151 } 1151 }
1152 case AsmTyper::kMathAtan: { 1152 case AsmTyper::kMathAtan: {
1153 VisitCallArgs(call); 1153 VisitCallArgs(call);
1154 DCHECK_EQ(kAstF64, call_type); 1154 DCHECK_EQ(kWasmF64, call_type);
1155 current_function_builder_->Emit(kExprF64Atan); 1155 current_function_builder_->Emit(kExprF64Atan);
1156 break; 1156 break;
1157 } 1157 }
1158 case AsmTyper::kMathCos: { 1158 case AsmTyper::kMathCos: {
1159 VisitCallArgs(call); 1159 VisitCallArgs(call);
1160 DCHECK_EQ(kAstF64, call_type); 1160 DCHECK_EQ(kWasmF64, call_type);
1161 current_function_builder_->Emit(kExprF64Cos); 1161 current_function_builder_->Emit(kExprF64Cos);
1162 break; 1162 break;
1163 } 1163 }
1164 case AsmTyper::kMathSin: { 1164 case AsmTyper::kMathSin: {
1165 VisitCallArgs(call); 1165 VisitCallArgs(call);
1166 DCHECK_EQ(kAstF64, call_type); 1166 DCHECK_EQ(kWasmF64, call_type);
1167 current_function_builder_->Emit(kExprF64Sin); 1167 current_function_builder_->Emit(kExprF64Sin);
1168 break; 1168 break;
1169 } 1169 }
1170 case AsmTyper::kMathTan: { 1170 case AsmTyper::kMathTan: {
1171 VisitCallArgs(call); 1171 VisitCallArgs(call);
1172 DCHECK_EQ(kAstF64, call_type); 1172 DCHECK_EQ(kWasmF64, call_type);
1173 current_function_builder_->Emit(kExprF64Tan); 1173 current_function_builder_->Emit(kExprF64Tan);
1174 break; 1174 break;
1175 } 1175 }
1176 case AsmTyper::kMathExp: { 1176 case AsmTyper::kMathExp: {
1177 VisitCallArgs(call); 1177 VisitCallArgs(call);
1178 DCHECK_EQ(kAstF64, call_type); 1178 DCHECK_EQ(kWasmF64, call_type);
1179 current_function_builder_->Emit(kExprF64Exp); 1179 current_function_builder_->Emit(kExprF64Exp);
1180 break; 1180 break;
1181 } 1181 }
1182 case AsmTyper::kMathLog: { 1182 case AsmTyper::kMathLog: {
1183 VisitCallArgs(call); 1183 VisitCallArgs(call);
1184 DCHECK_EQ(kAstF64, call_type); 1184 DCHECK_EQ(kWasmF64, call_type);
1185 current_function_builder_->Emit(kExprF64Log); 1185 current_function_builder_->Emit(kExprF64Log);
1186 break; 1186 break;
1187 } 1187 }
1188 case AsmTyper::kMathCeil: { 1188 case AsmTyper::kMathCeil: {
1189 VisitCallArgs(call); 1189 VisitCallArgs(call);
1190 if (call_type == kAstF32) { 1190 if (call_type == kWasmF32) {
1191 current_function_builder_->Emit(kExprF32Ceil); 1191 current_function_builder_->Emit(kExprF32Ceil);
1192 } else if (call_type == kAstF64) { 1192 } else if (call_type == kWasmF64) {
1193 current_function_builder_->Emit(kExprF64Ceil); 1193 current_function_builder_->Emit(kExprF64Ceil);
1194 } else { 1194 } else {
1195 UNREACHABLE(); 1195 UNREACHABLE();
1196 } 1196 }
1197 break; 1197 break;
1198 } 1198 }
1199 case AsmTyper::kMathFloor: { 1199 case AsmTyper::kMathFloor: {
1200 VisitCallArgs(call); 1200 VisitCallArgs(call);
1201 if (call_type == kAstF32) { 1201 if (call_type == kWasmF32) {
1202 current_function_builder_->Emit(kExprF32Floor); 1202 current_function_builder_->Emit(kExprF32Floor);
1203 } else if (call_type == kAstF64) { 1203 } else if (call_type == kWasmF64) {
1204 current_function_builder_->Emit(kExprF64Floor); 1204 current_function_builder_->Emit(kExprF64Floor);
1205 } else { 1205 } else {
1206 UNREACHABLE(); 1206 UNREACHABLE();
1207 } 1207 }
1208 break; 1208 break;
1209 } 1209 }
1210 case AsmTyper::kMathSqrt: { 1210 case AsmTyper::kMathSqrt: {
1211 VisitCallArgs(call); 1211 VisitCallArgs(call);
1212 if (call_type == kAstF32) { 1212 if (call_type == kWasmF32) {
1213 current_function_builder_->Emit(kExprF32Sqrt); 1213 current_function_builder_->Emit(kExprF32Sqrt);
1214 } else if (call_type == kAstF64) { 1214 } else if (call_type == kWasmF64) {
1215 current_function_builder_->Emit(kExprF64Sqrt); 1215 current_function_builder_->Emit(kExprF64Sqrt);
1216 } else { 1216 } else {
1217 UNREACHABLE(); 1217 UNREACHABLE();
1218 } 1218 }
1219 break; 1219 break;
1220 } 1220 }
1221 case AsmTyper::kMathClz32: { 1221 case AsmTyper::kMathClz32: {
1222 VisitCallArgs(call); 1222 VisitCallArgs(call);
1223 DCHECK(call_type == kAstI32); 1223 DCHECK(call_type == kWasmI32);
1224 current_function_builder_->Emit(kExprI32Clz); 1224 current_function_builder_->Emit(kExprI32Clz);
1225 break; 1225 break;
1226 } 1226 }
1227 case AsmTyper::kMathAbs: { 1227 case AsmTyper::kMathAbs: {
1228 if (call_type == kAstI32) { 1228 if (call_type == kWasmI32) {
1229 WasmTemporary tmp(current_function_builder_, kAstI32); 1229 WasmTemporary tmp(current_function_builder_, kWasmI32);
1230 1230
1231 // if set_local(tmp, x) < 0 1231 // if set_local(tmp, x) < 0
1232 Visit(call->arguments()->at(0)); 1232 Visit(call->arguments()->at(0));
1233 current_function_builder_->EmitTeeLocal(tmp.index()); 1233 current_function_builder_->EmitTeeLocal(tmp.index());
1234 byte code[] = {WASM_I8(0)}; 1234 byte code[] = {WASM_I8(0)};
1235 current_function_builder_->EmitCode(code, sizeof(code)); 1235 current_function_builder_->EmitCode(code, sizeof(code));
1236 current_function_builder_->Emit(kExprI32LtS); 1236 current_function_builder_->Emit(kExprI32LtS);
1237 current_function_builder_->EmitWithU8(kExprIf, kLocalI32); 1237 current_function_builder_->EmitWithU8(kExprIf, kLocalI32);
1238 1238
1239 // then (0 - tmp) 1239 // then (0 - tmp)
1240 current_function_builder_->EmitCode(code, sizeof(code)); 1240 current_function_builder_->EmitCode(code, sizeof(code));
1241 current_function_builder_->EmitGetLocal(tmp.index()); 1241 current_function_builder_->EmitGetLocal(tmp.index());
1242 current_function_builder_->Emit(kExprI32Sub); 1242 current_function_builder_->Emit(kExprI32Sub);
1243 1243
1244 // else tmp 1244 // else tmp
1245 current_function_builder_->Emit(kExprElse); 1245 current_function_builder_->Emit(kExprElse);
1246 current_function_builder_->EmitGetLocal(tmp.index()); 1246 current_function_builder_->EmitGetLocal(tmp.index());
1247 // end 1247 // end
1248 current_function_builder_->Emit(kExprEnd); 1248 current_function_builder_->Emit(kExprEnd);
1249 1249
1250 } else if (call_type == kAstF32) { 1250 } else if (call_type == kWasmF32) {
1251 VisitCallArgs(call); 1251 VisitCallArgs(call);
1252 current_function_builder_->Emit(kExprF32Abs); 1252 current_function_builder_->Emit(kExprF32Abs);
1253 } else if (call_type == kAstF64) { 1253 } else if (call_type == kWasmF64) {
1254 VisitCallArgs(call); 1254 VisitCallArgs(call);
1255 current_function_builder_->Emit(kExprF64Abs); 1255 current_function_builder_->Emit(kExprF64Abs);
1256 } else { 1256 } else {
1257 UNREACHABLE(); 1257 UNREACHABLE();
1258 } 1258 }
1259 break; 1259 break;
1260 } 1260 }
1261 case AsmTyper::kMathMin: { 1261 case AsmTyper::kMathMin: {
1262 // TODO(bradnelson): Change wasm to match Math.min in asm.js mode. 1262 // TODO(bradnelson): Change wasm to match Math.min in asm.js mode.
1263 if (call_type == kAstI32) { 1263 if (call_type == kWasmI32) {
1264 WasmTemporary tmp_x(current_function_builder_, kAstI32); 1264 WasmTemporary tmp_x(current_function_builder_, kWasmI32);
1265 WasmTemporary tmp_y(current_function_builder_, kAstI32); 1265 WasmTemporary tmp_y(current_function_builder_, kWasmI32);
1266 1266
1267 // if set_local(tmp_x, x) < set_local(tmp_y, y) 1267 // if set_local(tmp_x, x) < set_local(tmp_y, y)
1268 Visit(call->arguments()->at(0)); 1268 Visit(call->arguments()->at(0));
1269 current_function_builder_->EmitTeeLocal(tmp_x.index()); 1269 current_function_builder_->EmitTeeLocal(tmp_x.index());
1270 1270
1271 Visit(call->arguments()->at(1)); 1271 Visit(call->arguments()->at(1));
1272 current_function_builder_->EmitTeeLocal(tmp_y.index()); 1272 current_function_builder_->EmitTeeLocal(tmp_y.index());
1273 1273
1274 current_function_builder_->Emit(kExprI32LeS); 1274 current_function_builder_->Emit(kExprI32LeS);
1275 current_function_builder_->EmitWithU8(kExprIf, kLocalI32); 1275 current_function_builder_->EmitWithU8(kExprIf, kLocalI32);
1276 1276
1277 // then tmp_x 1277 // then tmp_x
1278 current_function_builder_->EmitGetLocal(tmp_x.index()); 1278 current_function_builder_->EmitGetLocal(tmp_x.index());
1279 1279
1280 // else tmp_y 1280 // else tmp_y
1281 current_function_builder_->Emit(kExprElse); 1281 current_function_builder_->Emit(kExprElse);
1282 current_function_builder_->EmitGetLocal(tmp_y.index()); 1282 current_function_builder_->EmitGetLocal(tmp_y.index());
1283 current_function_builder_->Emit(kExprEnd); 1283 current_function_builder_->Emit(kExprEnd);
1284 1284
1285 } else if (call_type == kAstF32) { 1285 } else if (call_type == kWasmF32) {
1286 VisitCallArgs(call); 1286 VisitCallArgs(call);
1287 current_function_builder_->Emit(kExprF32Min); 1287 current_function_builder_->Emit(kExprF32Min);
1288 } else if (call_type == kAstF64) { 1288 } else if (call_type == kWasmF64) {
1289 VisitCallArgs(call); 1289 VisitCallArgs(call);
1290 current_function_builder_->Emit(kExprF64Min); 1290 current_function_builder_->Emit(kExprF64Min);
1291 } else { 1291 } else {
1292 UNREACHABLE(); 1292 UNREACHABLE();
1293 } 1293 }
1294 break; 1294 break;
1295 } 1295 }
1296 case AsmTyper::kMathMax: { 1296 case AsmTyper::kMathMax: {
1297 // TODO(bradnelson): Change wasm to match Math.max in asm.js mode. 1297 // TODO(bradnelson): Change wasm to match Math.max in asm.js mode.
1298 if (call_type == kAstI32) { 1298 if (call_type == kWasmI32) {
1299 WasmTemporary tmp_x(current_function_builder_, kAstI32); 1299 WasmTemporary tmp_x(current_function_builder_, kWasmI32);
1300 WasmTemporary tmp_y(current_function_builder_, kAstI32); 1300 WasmTemporary tmp_y(current_function_builder_, kWasmI32);
1301 1301
1302 // if set_local(tmp_x, x) < set_local(tmp_y, y) 1302 // if set_local(tmp_x, x) < set_local(tmp_y, y)
1303 Visit(call->arguments()->at(0)); 1303 Visit(call->arguments()->at(0));
1304 1304
1305 current_function_builder_->EmitTeeLocal(tmp_x.index()); 1305 current_function_builder_->EmitTeeLocal(tmp_x.index());
1306 1306
1307 Visit(call->arguments()->at(1)); 1307 Visit(call->arguments()->at(1));
1308 current_function_builder_->EmitTeeLocal(tmp_y.index()); 1308 current_function_builder_->EmitTeeLocal(tmp_y.index());
1309 1309
1310 current_function_builder_->Emit(kExprI32LeS); 1310 current_function_builder_->Emit(kExprI32LeS);
1311 current_function_builder_->EmitWithU8(kExprIf, kLocalI32); 1311 current_function_builder_->EmitWithU8(kExprIf, kLocalI32);
1312 1312
1313 // then tmp_y 1313 // then tmp_y
1314 current_function_builder_->EmitGetLocal(tmp_y.index()); 1314 current_function_builder_->EmitGetLocal(tmp_y.index());
1315 1315
1316 // else tmp_x 1316 // else tmp_x
1317 current_function_builder_->Emit(kExprElse); 1317 current_function_builder_->Emit(kExprElse);
1318 current_function_builder_->EmitGetLocal(tmp_x.index()); 1318 current_function_builder_->EmitGetLocal(tmp_x.index());
1319 current_function_builder_->Emit(kExprEnd); 1319 current_function_builder_->Emit(kExprEnd);
1320 1320
1321 } else if (call_type == kAstF32) { 1321 } else if (call_type == kWasmF32) {
1322 VisitCallArgs(call); 1322 VisitCallArgs(call);
1323 current_function_builder_->Emit(kExprF32Max); 1323 current_function_builder_->Emit(kExprF32Max);
1324 } else if (call_type == kAstF64) { 1324 } else if (call_type == kWasmF64) {
1325 VisitCallArgs(call); 1325 VisitCallArgs(call);
1326 current_function_builder_->Emit(kExprF64Max); 1326 current_function_builder_->Emit(kExprF64Max);
1327 } else { 1327 } else {
1328 UNREACHABLE(); 1328 UNREACHABLE();
1329 } 1329 }
1330 break; 1330 break;
1331 } 1331 }
1332 case AsmTyper::kMathAtan2: { 1332 case AsmTyper::kMathAtan2: {
1333 VisitCallArgs(call); 1333 VisitCallArgs(call);
1334 DCHECK_EQ(kAstF64, call_type); 1334 DCHECK_EQ(kWasmF64, call_type);
1335 current_function_builder_->Emit(kExprF64Atan2); 1335 current_function_builder_->Emit(kExprF64Atan2);
1336 break; 1336 break;
1337 } 1337 }
1338 case AsmTyper::kMathPow: { 1338 case AsmTyper::kMathPow: {
1339 VisitCallArgs(call); 1339 VisitCallArgs(call);
1340 DCHECK_EQ(kAstF64, call_type); 1340 DCHECK_EQ(kWasmF64, call_type);
1341 current_function_builder_->Emit(kExprF64Pow); 1341 current_function_builder_->Emit(kExprF64Pow);
1342 break; 1342 break;
1343 } 1343 }
1344 case AsmTyper::kMathImul: { 1344 case AsmTyper::kMathImul: {
1345 VisitCallArgs(call); 1345 VisitCallArgs(call);
1346 current_function_builder_->Emit(kExprI32Mul); 1346 current_function_builder_->Emit(kExprI32Mul);
1347 break; 1347 break;
1348 } 1348 }
1349 case AsmTyper::kMathFround: { 1349 case AsmTyper::kMathFround: {
1350 DCHECK(args->length() == 1); 1350 DCHECK(args->length() == 1);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 typer_->VariableAsStandardMember(proxy->var()) == 1411 typer_->VariableAsStandardMember(proxy->var()) ==
1412 AsmTyper::kMathFround); 1412 AsmTyper::kMathFround);
1413 if (VisitStdlibFunction(expr, proxy)) { 1413 if (VisitStdlibFunction(expr, proxy)) {
1414 return true; 1414 return true;
1415 } 1415 }
1416 } 1416 }
1417 DCHECK(kFuncScope == scope_); 1417 DCHECK(kFuncScope == scope_);
1418 VariableProxy* vp = expr->expression()->AsVariableProxy(); 1418 VariableProxy* vp = expr->expression()->AsVariableProxy();
1419 DCHECK_NOT_NULL(vp); 1419 DCHECK_NOT_NULL(vp);
1420 if (typer_->TypeOf(vp)->AsFFIType() != nullptr) { 1420 if (typer_->TypeOf(vp)->AsFFIType() != nullptr) {
1421 LocalType return_type = TypeOf(expr); 1421 ValueType return_type = TypeOf(expr);
1422 ZoneList<Expression*>* args = expr->arguments(); 1422 ZoneList<Expression*>* args = expr->arguments();
1423 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1, 1423 FunctionSig::Builder sig(zone(), return_type == kWasmStmt ? 0 : 1,
1424 args->length()); 1424 args->length());
1425 if (return_type != kAstStmt) { 1425 if (return_type != kWasmStmt) {
1426 sig.AddReturn(return_type); 1426 sig.AddReturn(return_type);
1427 } else { 1427 } else {
1428 returns_value = false; 1428 returns_value = false;
1429 } 1429 }
1430 for (int i = 0; i < args->length(); ++i) { 1430 for (int i = 0; i < args->length(); ++i) {
1431 sig.AddParam(TypeOf(args->at(i))); 1431 sig.AddParam(TypeOf(args->at(i)));
1432 } 1432 }
1433 uint32_t index = imported_function_table_.LookupOrInsertImportUse( 1433 uint32_t index = imported_function_table_.LookupOrInsertImportUse(
1434 vp->var(), sig.Build()); 1434 vp->var(), sig.Build());
1435 VisitCallArgs(expr); 1435 VisitCallArgs(expr);
(...skipping 23 matching lines...) Expand all
1459 Property* p = expr->expression()->AsProperty(); 1459 Property* p = expr->expression()->AsProperty();
1460 DCHECK_NOT_NULL(p); 1460 DCHECK_NOT_NULL(p);
1461 VariableProxy* var = p->obj()->AsVariableProxy(); 1461 VariableProxy* var = p->obj()->AsVariableProxy();
1462 DCHECK_NOT_NULL(var); 1462 DCHECK_NOT_NULL(var);
1463 FunctionTableIndices* indices = LookupOrAddFunctionTable(var, p); 1463 FunctionTableIndices* indices = LookupOrAddFunctionTable(var, p);
1464 Visit(p->key()); // TODO(titzer): should use RECURSE() 1464 Visit(p->key()); // TODO(titzer): should use RECURSE()
1465 1465
1466 // We have to use a temporary for the correct order of evaluation. 1466 // We have to use a temporary for the correct order of evaluation.
1467 current_function_builder_->EmitI32Const(indices->start_index); 1467 current_function_builder_->EmitI32Const(indices->start_index);
1468 current_function_builder_->Emit(kExprI32Add); 1468 current_function_builder_->Emit(kExprI32Add);
1469 WasmTemporary tmp(current_function_builder_, kAstI32); 1469 WasmTemporary tmp(current_function_builder_, kWasmI32);
1470 current_function_builder_->EmitSetLocal(tmp.index()); 1470 current_function_builder_->EmitSetLocal(tmp.index());
1471 1471
1472 VisitCallArgs(expr); 1472 VisitCallArgs(expr);
1473 1473
1474 current_function_builder_->EmitGetLocal(tmp.index()); 1474 current_function_builder_->EmitGetLocal(tmp.index());
1475 current_function_builder_->AddAsmWasmOffset(expr->position(), 1475 current_function_builder_->AddAsmWasmOffset(expr->position(),
1476 expr->position()); 1476 expr->position());
1477 current_function_builder_->Emit(kExprCallIndirect); 1477 current_function_builder_->Emit(kExprCallIndirect);
1478 current_function_builder_->EmitVarInt(indices->signature_index); 1478 current_function_builder_->EmitVarInt(indices->signature_index);
1479 current_function_builder_->EmitVarInt(0); // table index 1479 current_function_builder_->EmitVarInt(0); // table index
1480 returns_value = 1480 returns_value =
1481 builder_->GetSignature(indices->signature_index)->return_count() > 1481 builder_->GetSignature(indices->signature_index)->return_count() >
1482 0; 1482 0;
1483 break; 1483 break;
1484 } 1484 }
1485 default: 1485 default:
1486 UNREACHABLE(); 1486 UNREACHABLE();
1487 } 1487 }
1488 return returns_value; 1488 return returns_value;
1489 } 1489 }
1490 1490
1491 void VisitCallNew(CallNew* expr) { UNREACHABLE(); } 1491 void VisitCallNew(CallNew* expr) { UNREACHABLE(); }
1492 1492
1493 void VisitCallRuntime(CallRuntime* expr) { UNREACHABLE(); } 1493 void VisitCallRuntime(CallRuntime* expr) { UNREACHABLE(); }
1494 1494
1495 void VisitUnaryOperation(UnaryOperation* expr) { 1495 void VisitUnaryOperation(UnaryOperation* expr) {
1496 RECURSE(Visit(expr->expression())); 1496 RECURSE(Visit(expr->expression()));
1497 switch (expr->op()) { 1497 switch (expr->op()) {
1498 case Token::NOT: { 1498 case Token::NOT: {
1499 DCHECK_EQ(kAstI32, TypeOf(expr->expression())); 1499 DCHECK_EQ(kWasmI32, TypeOf(expr->expression()));
1500 current_function_builder_->Emit(kExprI32Eqz); 1500 current_function_builder_->Emit(kExprI32Eqz);
1501 break; 1501 break;
1502 } 1502 }
1503 default: 1503 default:
1504 UNREACHABLE(); 1504 UNREACHABLE();
1505 } 1505 }
1506 } 1506 }
1507 1507
1508 void VisitCountOperation(CountOperation* expr) { UNREACHABLE(); } 1508 void VisitCountOperation(CountOperation* expr) { UNREACHABLE(); }
1509 1509
1510 bool MatchIntBinaryOperation(BinaryOperation* expr, Token::Value op, 1510 bool MatchIntBinaryOperation(BinaryOperation* expr, Token::Value op,
1511 int32_t val) { 1511 int32_t val) {
1512 DCHECK_NOT_NULL(expr->right()); 1512 DCHECK_NOT_NULL(expr->right());
1513 if (expr->op() == op && expr->right()->IsLiteral() && 1513 if (expr->op() == op && expr->right()->IsLiteral() &&
1514 TypeOf(expr) == kAstI32) { 1514 TypeOf(expr) == kWasmI32) {
1515 Literal* right = expr->right()->AsLiteral(); 1515 Literal* right = expr->right()->AsLiteral();
1516 if (right->raw_value()->IsNumber() && 1516 if (right->raw_value()->IsNumber() &&
1517 static_cast<int32_t>(right->raw_value()->AsNumber()) == val) { 1517 static_cast<int32_t>(right->raw_value()->AsNumber()) == val) {
1518 return true; 1518 return true;
1519 } 1519 }
1520 } 1520 }
1521 return false; 1521 return false;
1522 } 1522 }
1523 1523
1524 bool MatchDoubleBinaryOperation(BinaryOperation* expr, Token::Value op, 1524 bool MatchDoubleBinaryOperation(BinaryOperation* expr, Token::Value op,
1525 double val) { 1525 double val) {
1526 DCHECK_NOT_NULL(expr->right()); 1526 DCHECK_NOT_NULL(expr->right());
1527 if (expr->op() == op && expr->right()->IsLiteral() && 1527 if (expr->op() == op && expr->right()->IsLiteral() &&
1528 TypeOf(expr) == kAstF64) { 1528 TypeOf(expr) == kWasmF64) {
1529 Literal* right = expr->right()->AsLiteral(); 1529 Literal* right = expr->right()->AsLiteral();
1530 DCHECK(right->raw_value()->IsNumber()); 1530 DCHECK(right->raw_value()->IsNumber());
1531 if (right->raw_value()->AsNumber() == val) { 1531 if (right->raw_value()->AsNumber() == val) {
1532 return true; 1532 return true;
1533 } 1533 }
1534 } 1534 }
1535 return false; 1535 return false;
1536 } 1536 }
1537 1537
1538 enum ConvertOperation { kNone, kAsIs, kToInt, kToDouble }; 1538 enum ConvertOperation { kNone, kAsIs, kToInt, kToDouble };
1539 1539
1540 ConvertOperation MatchOr(BinaryOperation* expr) { 1540 ConvertOperation MatchOr(BinaryOperation* expr) {
1541 if (MatchIntBinaryOperation(expr, Token::BIT_OR, 0) && 1541 if (MatchIntBinaryOperation(expr, Token::BIT_OR, 0) &&
1542 (TypeOf(expr->left()) == kAstI32)) { 1542 (TypeOf(expr->left()) == kWasmI32)) {
1543 return kAsIs; 1543 return kAsIs;
1544 } else { 1544 } else {
1545 return kNone; 1545 return kNone;
1546 } 1546 }
1547 } 1547 }
1548 1548
1549 ConvertOperation MatchShr(BinaryOperation* expr) { 1549 ConvertOperation MatchShr(BinaryOperation* expr) {
1550 if (MatchIntBinaryOperation(expr, Token::SHR, 0)) { 1550 if (MatchIntBinaryOperation(expr, Token::SHR, 0)) {
1551 // TODO(titzer): this probably needs to be kToUint 1551 // TODO(titzer): this probably needs to be kToUint
1552 return (TypeOf(expr->left()) == kAstI32) ? kAsIs : kToInt; 1552 return (TypeOf(expr->left()) == kWasmI32) ? kAsIs : kToInt;
1553 } else { 1553 } else {
1554 return kNone; 1554 return kNone;
1555 } 1555 }
1556 } 1556 }
1557 1557
1558 ConvertOperation MatchXor(BinaryOperation* expr) { 1558 ConvertOperation MatchXor(BinaryOperation* expr) {
1559 if (MatchIntBinaryOperation(expr, Token::BIT_XOR, 0xffffffff)) { 1559 if (MatchIntBinaryOperation(expr, Token::BIT_XOR, 0xffffffff)) {
1560 DCHECK_EQ(kAstI32, TypeOf(expr->left())); 1560 DCHECK_EQ(kWasmI32, TypeOf(expr->left()));
1561 DCHECK_EQ(kAstI32, TypeOf(expr->right())); 1561 DCHECK_EQ(kWasmI32, TypeOf(expr->right()));
1562 BinaryOperation* op = expr->left()->AsBinaryOperation(); 1562 BinaryOperation* op = expr->left()->AsBinaryOperation();
1563 if (op != nullptr) { 1563 if (op != nullptr) {
1564 if (MatchIntBinaryOperation(op, Token::BIT_XOR, 0xffffffff)) { 1564 if (MatchIntBinaryOperation(op, Token::BIT_XOR, 0xffffffff)) {
1565 DCHECK_EQ(kAstI32, TypeOf(op->right())); 1565 DCHECK_EQ(kWasmI32, TypeOf(op->right()));
1566 if (TypeOf(op->left()) != kAstI32) { 1566 if (TypeOf(op->left()) != kWasmI32) {
1567 return kToInt; 1567 return kToInt;
1568 } else { 1568 } else {
1569 return kAsIs; 1569 return kAsIs;
1570 } 1570 }
1571 } 1571 }
1572 } 1572 }
1573 } 1573 }
1574 return kNone; 1574 return kNone;
1575 } 1575 }
1576 1576
1577 ConvertOperation MatchMul(BinaryOperation* expr) { 1577 ConvertOperation MatchMul(BinaryOperation* expr) {
1578 if (MatchDoubleBinaryOperation(expr, Token::MUL, 1.0)) { 1578 if (MatchDoubleBinaryOperation(expr, Token::MUL, 1.0)) {
1579 DCHECK_EQ(kAstF64, TypeOf(expr->right())); 1579 DCHECK_EQ(kWasmF64, TypeOf(expr->right()));
1580 if (TypeOf(expr->left()) != kAstF64) { 1580 if (TypeOf(expr->left()) != kWasmF64) {
1581 return kToDouble; 1581 return kToDouble;
1582 } else { 1582 } else {
1583 return kAsIs; 1583 return kAsIs;
1584 } 1584 }
1585 } else { 1585 } else {
1586 return kNone; 1586 return kNone;
1587 } 1587 }
1588 } 1588 }
1589 1589
1590 ConvertOperation MatchBinaryOperation(BinaryOperation* expr) { 1590 ConvertOperation MatchBinaryOperation(BinaryOperation* expr) {
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1829 } 1829 }
1830 1830
1831 void VisitDoExpression(DoExpression* expr) { UNREACHABLE(); } 1831 void VisitDoExpression(DoExpression* expr) { UNREACHABLE(); }
1832 1832
1833 void VisitRewritableExpression(RewritableExpression* expr) { UNREACHABLE(); } 1833 void VisitRewritableExpression(RewritableExpression* expr) { UNREACHABLE(); }
1834 1834
1835 struct IndexContainer : public ZoneObject { 1835 struct IndexContainer : public ZoneObject {
1836 uint32_t index; 1836 uint32_t index;
1837 }; 1837 };
1838 1838
1839 uint32_t LookupOrInsertLocal(Variable* v, LocalType type) { 1839 uint32_t LookupOrInsertLocal(Variable* v, ValueType type) {
1840 DCHECK_NOT_NULL(current_function_builder_); 1840 DCHECK_NOT_NULL(current_function_builder_);
1841 ZoneHashMap::Entry* entry = 1841 ZoneHashMap::Entry* entry =
1842 local_variables_.Lookup(v, ComputePointerHash(v)); 1842 local_variables_.Lookup(v, ComputePointerHash(v));
1843 if (entry == nullptr) { 1843 if (entry == nullptr) {
1844 uint32_t index; 1844 uint32_t index;
1845 DCHECK(!v->IsParameter()); 1845 DCHECK(!v->IsParameter());
1846 index = current_function_builder_->AddLocal(type); 1846 index = current_function_builder_->AddLocal(type);
1847 IndexContainer* container = new (zone()) IndexContainer(); 1847 IndexContainer* container = new (zone()) IndexContainer();
1848 container->index = index; 1848 container->index = index;
1849 entry = local_variables_.LookupOrInsert(v, ComputePointerHash(v), 1849 entry = local_variables_.LookupOrInsert(v, ComputePointerHash(v),
1850 ZoneAllocationPolicy(zone())); 1850 ZoneAllocationPolicy(zone()));
1851 entry->value = container; 1851 entry->value = container;
1852 } 1852 }
1853 return (reinterpret_cast<IndexContainer*>(entry->value))->index; 1853 return (reinterpret_cast<IndexContainer*>(entry->value))->index;
1854 } 1854 }
1855 1855
1856 void InsertParameter(Variable* v, LocalType type, uint32_t index) { 1856 void InsertParameter(Variable* v, ValueType type, uint32_t index) {
1857 DCHECK(v->IsParameter()); 1857 DCHECK(v->IsParameter());
1858 DCHECK_NOT_NULL(current_function_builder_); 1858 DCHECK_NOT_NULL(current_function_builder_);
1859 ZoneHashMap::Entry* entry = 1859 ZoneHashMap::Entry* entry =
1860 local_variables_.Lookup(v, ComputePointerHash(v)); 1860 local_variables_.Lookup(v, ComputePointerHash(v));
1861 DCHECK_NULL(entry); 1861 DCHECK_NULL(entry);
1862 IndexContainer* container = new (zone()) IndexContainer(); 1862 IndexContainer* container = new (zone()) IndexContainer();
1863 container->index = index; 1863 container->index = index;
1864 entry = local_variables_.LookupOrInsert(v, ComputePointerHash(v), 1864 entry = local_variables_.LookupOrInsert(v, ComputePointerHash(v),
1865 ZoneAllocationPolicy(zone())); 1865 ZoneAllocationPolicy(zone()));
1866 entry->value = container; 1866 entry->value = container;
1867 } 1867 }
1868 1868
1869 uint32_t LookupOrInsertGlobal(Variable* v, LocalType type) { 1869 uint32_t LookupOrInsertGlobal(Variable* v, ValueType type) {
1870 ZoneHashMap::Entry* entry = 1870 ZoneHashMap::Entry* entry =
1871 global_variables_.Lookup(v, ComputePointerHash(v)); 1871 global_variables_.Lookup(v, ComputePointerHash(v));
1872 if (entry == nullptr) { 1872 if (entry == nullptr) {
1873 uint32_t index = builder_->AddGlobal(type, 0); 1873 uint32_t index = builder_->AddGlobal(type, 0);
1874 IndexContainer* container = new (zone()) IndexContainer(); 1874 IndexContainer* container = new (zone()) IndexContainer();
1875 container->index = index; 1875 container->index = index;
1876 entry = global_variables_.LookupOrInsert(v, ComputePointerHash(v), 1876 entry = global_variables_.LookupOrInsert(v, ComputePointerHash(v),
1877 ZoneAllocationPolicy(zone())); 1877 ZoneAllocationPolicy(zone()));
1878 entry->value = container; 1878 entry->value = container;
1879 } 1879 }
1880 return (reinterpret_cast<IndexContainer*>(entry->value))->index; 1880 return (reinterpret_cast<IndexContainer*>(entry->value))->index;
1881 } 1881 }
1882 1882
1883 WasmFunctionBuilder* LookupOrInsertFunction(Variable* v) { 1883 WasmFunctionBuilder* LookupOrInsertFunction(Variable* v) {
1884 DCHECK_NOT_NULL(builder_); 1884 DCHECK_NOT_NULL(builder_);
1885 ZoneHashMap::Entry* entry = functions_.Lookup(v, ComputePointerHash(v)); 1885 ZoneHashMap::Entry* entry = functions_.Lookup(v, ComputePointerHash(v));
1886 if (entry == nullptr) { 1886 if (entry == nullptr) {
1887 auto* func_type = typer_->TypeOf(v)->AsFunctionType(); 1887 auto* func_type = typer_->TypeOf(v)->AsFunctionType();
1888 DCHECK_NOT_NULL(func_type); 1888 DCHECK_NOT_NULL(func_type);
1889 // Build the signature for the function. 1889 // Build the signature for the function.
1890 LocalType return_type = TypeFrom(func_type->ReturnType()); 1890 ValueType return_type = TypeFrom(func_type->ReturnType());
1891 const auto& arguments = func_type->Arguments(); 1891 const auto& arguments = func_type->Arguments();
1892 FunctionSig::Builder b(zone(), return_type == kAstStmt ? 0 : 1, 1892 FunctionSig::Builder b(zone(), return_type == kWasmStmt ? 0 : 1,
1893 arguments.size()); 1893 arguments.size());
1894 if (return_type != kAstStmt) b.AddReturn(return_type); 1894 if (return_type != kWasmStmt) b.AddReturn(return_type);
1895 for (int i = 0; i < static_cast<int>(arguments.size()); ++i) { 1895 for (int i = 0; i < static_cast<int>(arguments.size()); ++i) {
1896 LocalType type = TypeFrom(arguments[i]); 1896 ValueType type = TypeFrom(arguments[i]);
1897 DCHECK_NE(kAstStmt, type); 1897 DCHECK_NE(kWasmStmt, type);
1898 b.AddParam(type); 1898 b.AddParam(type);
1899 } 1899 }
1900 1900
1901 WasmFunctionBuilder* function = builder_->AddFunction(b.Build()); 1901 WasmFunctionBuilder* function = builder_->AddFunction(b.Build());
1902 entry = functions_.LookupOrInsert(v, ComputePointerHash(v), 1902 entry = functions_.LookupOrInsert(v, ComputePointerHash(v),
1903 ZoneAllocationPolicy(zone())); 1903 ZoneAllocationPolicy(zone()));
1904 function->SetName( 1904 function->SetName(
1905 {reinterpret_cast<const char*>(v->raw_name()->raw_data()), 1905 {reinterpret_cast<const char*>(v->raw_name()->raw_data()),
1906 v->raw_name()->length()}); 1906 v->raw_name()->length()});
1907 entry->value = function; 1907 entry->value = function;
1908 } 1908 }
1909 return (reinterpret_cast<WasmFunctionBuilder*>(entry->value)); 1909 return (reinterpret_cast<WasmFunctionBuilder*>(entry->value));
1910 } 1910 }
1911 1911
1912 LocalType TypeOf(Expression* expr) { return TypeFrom(typer_->TypeOf(expr)); } 1912 ValueType TypeOf(Expression* expr) { return TypeFrom(typer_->TypeOf(expr)); }
1913 1913
1914 LocalType TypeFrom(AsmType* type) { 1914 ValueType TypeFrom(AsmType* type) {
1915 if (type->IsA(AsmType::Intish())) { 1915 if (type->IsA(AsmType::Intish())) {
1916 return kAstI32; 1916 return kWasmI32;
1917 } 1917 }
1918 1918
1919 if (type->IsA(AsmType::Floatish())) { 1919 if (type->IsA(AsmType::Floatish())) {
1920 return kAstF32; 1920 return kWasmF32;
1921 } 1921 }
1922 1922
1923 if (type->IsA(AsmType::DoubleQ())) { 1923 if (type->IsA(AsmType::DoubleQ())) {
1924 return kAstF64; 1924 return kWasmF64;
1925 } 1925 }
1926 1926
1927 return kAstStmt; 1927 return kWasmStmt;
1928 } 1928 }
1929 1929
1930 Zone* zone() { return zone_; } 1930 Zone* zone() { return zone_; }
1931 1931
1932 ZoneHashMap local_variables_; 1932 ZoneHashMap local_variables_;
1933 ZoneHashMap functions_; 1933 ZoneHashMap functions_;
1934 ZoneHashMap global_variables_; 1934 ZoneHashMap global_variables_;
1935 AsmScope scope_; 1935 AsmScope scope_;
1936 WasmModuleBuilder* builder_; 1936 WasmModuleBuilder* builder_;
1937 WasmFunctionBuilder* current_function_builder_; 1937 WasmFunctionBuilder* current_function_builder_;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1979 impl.builder_->WriteAsmJsOffsetTable(*asm_offsets_buffer); 1979 impl.builder_->WriteAsmJsOffsetTable(*asm_offsets_buffer);
1980 return {module_buffer, asm_offsets_buffer, success}; 1980 return {module_buffer, asm_offsets_buffer, success};
1981 } 1981 }
1982 1982
1983 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__"; 1983 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__";
1984 const char* AsmWasmBuilder::single_function_name = "__single_function__"; 1984 const char* AsmWasmBuilder::single_function_name = "__single_function__";
1985 1985
1986 } // namespace wasm 1986 } // namespace wasm
1987 } // namespace internal 1987 } // namespace internal
1988 } // namespace v8 1988 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/wasm-compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698