OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |