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

Side by Side Diff: src/typing-asm.cc

Issue 1642993002: Accurately type foreign functions, and variables. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix Created 4 years, 10 months 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
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/typing-asm.h" 5 #include "src/typing-asm.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 18 matching lines...) Expand all
29 29
30 30
31 #define RECURSE(call) \ 31 #define RECURSE(call) \
32 do { \ 32 do { \
33 DCHECK(!HasStackOverflow()); \ 33 DCHECK(!HasStackOverflow()); \
34 call; \ 34 call; \
35 if (HasStackOverflow()) return; \ 35 if (HasStackOverflow()) return; \
36 if (!valid_) return; \ 36 if (!valid_) return; \
37 } while (false) 37 } while (false)
38 38
39
40 AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Script* script, 39 AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Script* script,
41 FunctionLiteral* root) 40 FunctionLiteral* root)
42 : zone_(zone), 41 : zone_(zone),
43 isolate_(isolate), 42 isolate_(isolate),
44 script_(script), 43 script_(script),
45 root_(root), 44 root_(root),
46 valid_(true), 45 valid_(true),
47 allow_simd_(false), 46 allow_simd_(false),
48 property_info_(NULL), 47 property_info_(NULL),
49 intish_(0), 48 intish_(0),
50 stdlib_types_(zone), 49 stdlib_types_(zone),
51 stdlib_heap_types_(zone), 50 stdlib_heap_types_(zone),
52 stdlib_math_types_(zone), 51 stdlib_math_types_(zone),
53 #define V(NAME, Name, name, lane_count, lane_type) \ 52 #define V(NAME, Name, name, lane_count, lane_type) \
54 stdlib_simd_##name##_types_(zone), 53 stdlib_simd_##name##_types_(zone),
55 SIMD128_TYPES(V) 54 SIMD128_TYPES(V)
56 #undef V 55 #undef V
57 global_variable_type_(HashMap::PointersMatch, 56 global_variable_type_(HashMap::PointersMatch,
58 ZoneHashMap::kDefaultHashMapCapacity, 57 ZoneHashMap::kDefaultHashMapCapacity,
59 ZoneAllocationPolicy(zone)), 58 ZoneAllocationPolicy(zone)),
60 local_variable_type_(HashMap::PointersMatch, 59 local_variable_type_(HashMap::PointersMatch,
61 ZoneHashMap::kDefaultHashMapCapacity, 60 ZoneHashMap::kDefaultHashMapCapacity,
62 ZoneAllocationPolicy(zone)), 61 ZoneAllocationPolicy(zone)),
63 in_function_(false), 62 in_function_(false),
64 building_function_tables_(false), 63 building_function_tables_(false),
64 visiting_exports_(false),
65 cache_(TypeCache::Get()) { 65 cache_(TypeCache::Get()) {
66 InitializeAstVisitor(isolate); 66 InitializeAstVisitor(isolate);
67 InitializeStdlib(); 67 InitializeStdlib();
68 } 68 }
69 69
70 70
71 bool AsmTyper::Validate() { 71 bool AsmTyper::Validate() {
72 VisitAsmModule(root_); 72 VisitAsmModule(root_);
73 return valid_ && !HasStackOverflow(); 73 return valid_ && !HasStackOverflow();
74 } 74 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 if (decl != NULL) { 128 if (decl != NULL) {
129 RECURSE( 129 RECURSE(
130 VisitWithExpectation(decl->fun(), Type::Any(zone()), "UNREACHABLE")); 130 VisitWithExpectation(decl->fun(), Type::Any(zone()), "UNREACHABLE"));
131 if (!computed_type_->IsFunction()) { 131 if (!computed_type_->IsFunction()) {
132 FAIL(decl->fun(), "function literal expected to be a function"); 132 FAIL(decl->fun(), "function literal expected to be a function");
133 } 133 }
134 } 134 }
135 } 135 }
136 136
137 // Validate exports. 137 // Validate exports.
138 visiting_exports_ = true;
138 ReturnStatement* stmt = fun->body()->last()->AsReturnStatement(); 139 ReturnStatement* stmt = fun->body()->last()->AsReturnStatement();
139 if (stmt == nullptr) { 140 if (stmt == nullptr) {
140 FAIL(fun->body()->last(), "last statement in module is not a return"); 141 FAIL(fun->body()->last(), "last statement in module is not a return");
141 } 142 }
142 RECURSE(VisitWithExpectation(stmt->expression(), Type::Object(), 143 RECURSE(VisitWithExpectation(stmt->expression(), Type::Object(),
143 "expected object export")); 144 "expected object export"));
144 } 145 }
145 146
146 147
147 void AsmTyper::VisitVariableDeclaration(VariableDeclaration* decl) { 148 void AsmTyper::VisitVariableDeclaration(VariableDeclaration* decl) {
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 FAIL(stmt, "try statement encountered"); 483 FAIL(stmt, "try statement encountered");
483 } 484 }
484 485
485 486
486 void AsmTyper::VisitDebuggerStatement(DebuggerStatement* stmt) { 487 void AsmTyper::VisitDebuggerStatement(DebuggerStatement* stmt) {
487 FAIL(stmt, "debugger statement encountered"); 488 FAIL(stmt, "debugger statement encountered");
488 } 489 }
489 490
490 491
491 void AsmTyper::VisitFunctionLiteral(FunctionLiteral* expr) { 492 void AsmTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
492 Scope* scope = expr->scope();
493 DCHECK(scope->is_function_scope());
494 if (in_function_) { 493 if (in_function_) {
495 FAIL(expr, "invalid nested function"); 494 FAIL(expr, "invalid nested function");
496 } 495 }
496 Scope* scope = expr->scope();
497 DCHECK(scope->is_function_scope());
497 498
498 if (!expr->bounds().upper->IsFunction()) { 499 if (!expr->bounds().upper->IsFunction()) {
499 FAIL(expr, "invalid function literal"); 500 FAIL(expr, "invalid function literal");
500 } 501 }
501 502
502 Type::FunctionType* type = expr->bounds().upper->AsFunction(); 503 Type::FunctionType* type = expr->bounds().upper->AsFunction();
503 Type* save_return_type = return_type_; 504 Type* save_return_type = return_type_;
504 return_type_ = type->Result(); 505 return_type_ = type->Result();
505 in_function_ = true; 506 in_function_ = true;
506 local_variable_type_.Clear(); 507 local_variable_type_.Clear();
507 RECURSE(VisitDeclarations(scope->declarations())); 508 RECURSE(VisitDeclarations(scope->declarations()));
508 RECURSE(VisitStatements(expr->body())); 509 RECURSE(VisitStatements(expr->body()));
509 in_function_ = false; 510 in_function_ = false;
510 return_type_ = save_return_type; 511 return_type_ = save_return_type;
511 IntersectResult(expr, type); 512 IntersectResult(expr, type);
512 } 513 }
513 514
514 515
515 void AsmTyper::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { 516 void AsmTyper::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
516 FAIL(expr, "function info literal encountered"); 517 FAIL(expr, "function info literal encountered");
517 } 518 }
518 519
519 520
520 void AsmTyper::VisitDoExpression(DoExpression* expr) { 521 void AsmTyper::VisitDoExpression(DoExpression* expr) {
521 FAIL(expr, "do-expression encountered"); 522 FAIL(expr, "do-expression encountered");
522 } 523 }
523 524
524 525
525 void AsmTyper::VisitConditional(Conditional* expr) { 526 void AsmTyper::VisitConditional(Conditional* expr) {
527 if (!in_function_) {
528 FAIL(expr, "ternary operator inside module body");
529 }
526 RECURSE(VisitWithExpectation(expr->condition(), Type::Number(), 530 RECURSE(VisitWithExpectation(expr->condition(), Type::Number(),
527 "condition expected to be integer")); 531 "condition expected to be integer"));
528 if (!computed_type_->Is(cache_.kAsmInt)) { 532 if (!computed_type_->Is(cache_.kAsmInt)) {
529 FAIL(expr->condition(), "condition must be of type int"); 533 FAIL(expr->condition(), "condition must be of type int");
530 } 534 }
531 535
532 RECURSE(VisitWithExpectation( 536 RECURSE(VisitWithExpectation(
533 expr->then_expression(), expected_type_, 537 expr->then_expression(), expected_type_,
534 "conditional then branch type mismatch with enclosing expression")); 538 "conditional then branch type mismatch with enclosing expression"));
535 Type* then_type = StorageType(computed_type_); 539 Type* then_type = StorageType(computed_type_);
(...skipping 11 matching lines...) Expand all
547 551
548 if (!then_type->Is(else_type) || !else_type->Is(then_type)) { 552 if (!then_type->Is(else_type) || !else_type->Is(then_type)) {
549 FAIL(expr, "then and else expressions in ? must have the same type"); 553 FAIL(expr, "then and else expressions in ? must have the same type");
550 } 554 }
551 555
552 IntersectResult(expr, then_type); 556 IntersectResult(expr, then_type);
553 } 557 }
554 558
555 559
556 void AsmTyper::VisitVariableProxy(VariableProxy* expr) { 560 void AsmTyper::VisitVariableProxy(VariableProxy* expr) {
561 VisitVariableProxy(expr, false);
562 }
563
564 void AsmTyper::VisitVariableProxy(VariableProxy* expr, bool assignment) {
557 Variable* var = expr->var(); 565 Variable* var = expr->var();
558 VariableInfo* info = GetVariableInfo(var, false); 566 VariableInfo* info = GetVariableInfo(var, false);
567 if (!assignment && !in_function_ && !building_function_tables_ &&
568 !visiting_exports_) {
569 if (var->location() != VariableLocation::PARAMETER || var->index() >= 3) {
570 FAIL(expr, "illegal variable reference in module body");
571 }
572 }
559 if (info == NULL || info->type == NULL) { 573 if (info == NULL || info->type == NULL) {
560 if (var->mode() == TEMPORARY) { 574 if (var->mode() == TEMPORARY) {
561 SetType(var, Type::Any(zone())); 575 SetType(var, Type::Any(zone()));
562 info = GetVariableInfo(var, false); 576 info = GetVariableInfo(var, false);
563 } else { 577 } else {
564 FAIL(expr, "unbound variable"); 578 FAIL(expr, "unbound variable");
565 } 579 }
566 } 580 }
567 if (property_info_ != NULL) { 581 if (property_info_ != NULL) {
568 SetVariableInfo(var, property_info_); 582 SetVariableInfo(var, property_info_);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 } 682 }
669 if (expr->is_compound()) FAIL(expr, "compound assignment encountered"); 683 if (expr->is_compound()) FAIL(expr, "compound assignment encountered");
670 Type* type = expected_type_; 684 Type* type = expected_type_;
671 RECURSE(VisitWithExpectation( 685 RECURSE(VisitWithExpectation(
672 expr->value(), type, "assignment value expected to match surrounding")); 686 expr->value(), type, "assignment value expected to match surrounding"));
673 Type* target_type = StorageType(computed_type_); 687 Type* target_type = StorageType(computed_type_);
674 if (intish_ != 0) { 688 if (intish_ != 0) {
675 FAIL(expr, "intish or floatish assignment"); 689 FAIL(expr, "intish or floatish assignment");
676 } 690 }
677 if (expr->target()->IsVariableProxy()) { 691 if (expr->target()->IsVariableProxy()) {
678 RECURSE(VisitWithExpectation(expr->target(), target_type, 692 expected_type_ = target_type;
679 "assignment target expected to match value")); 693 VisitVariableProxy(expr->target()->AsVariableProxy(), true);
680 } else if (expr->target()->IsProperty()) { 694 } else if (expr->target()->IsProperty()) {
681 Property* property = expr->target()->AsProperty(); 695 Property* property = expr->target()->AsProperty();
682 RECURSE(VisitWithExpectation(property->obj(), Type::Any(), 696 RECURSE(VisitWithExpectation(property->obj(), Type::Any(),
683 "bad propety object")); 697 "bad propety object"));
684 if (!computed_type_->IsArray()) { 698 if (!computed_type_->IsArray()) {
685 FAIL(property->obj(), "array expected"); 699 FAIL(property->obj(), "array expected");
686 } 700 }
687 VisitHeapAccess(property, true, target_type); 701 VisitHeapAccess(property, true, target_type);
688 } 702 }
689 IntersectResult(expr, target_type); 703 IntersectResult(expr, target_type);
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 SetResult(expr, expected_type_); 919 SetResult(expr, expected_type_);
906 return; 920 return;
907 } 921 }
908 } 922 }
909 923
910 FAIL(expr, "invalid property access"); 924 FAIL(expr, "invalid property access");
911 } 925 }
912 926
913 927
914 void AsmTyper::VisitCall(Call* expr) { 928 void AsmTyper::VisitCall(Call* expr) {
929 Type* expected_type = expected_type_;
915 RECURSE(VisitWithExpectation(expr->expression(), Type::Any(), 930 RECURSE(VisitWithExpectation(expr->expression(), Type::Any(),
916 "callee expected to be any")); 931 "callee expected to be any"));
917 StandardMember standard_member = kNone; 932 StandardMember standard_member = kNone;
918 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 933 VariableProxy* proxy = expr->expression()->AsVariableProxy();
919 if (proxy) { 934 if (proxy) {
920 standard_member = VariableAsStandardMember(proxy->var()); 935 standard_member = VariableAsStandardMember(proxy->var());
921 } 936 }
922 if (!in_function_ && (proxy == NULL || standard_member != kMathFround)) { 937 if (!in_function_ && (proxy == NULL || standard_member != kMathFround)) {
923 FAIL(expr, "calls forbidden outside function bodies"); 938 FAIL(expr, "calls forbidden outside function bodies");
924 } 939 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 } 982 }
968 intish_ = 0; 983 intish_ = 0;
969 IntersectResult(expr, result_type); 984 IntersectResult(expr, result_type);
970 } else if (computed_type_->Is(Type::Any())) { 985 } else if (computed_type_->Is(Type::Any())) {
971 // For foreign calls. 986 // For foreign calls.
972 ZoneList<Expression*>* args = expr->arguments(); 987 ZoneList<Expression*>* args = expr->arguments();
973 for (int i = 0; i < args->length(); ++i) { 988 for (int i = 0; i < args->length(); ++i) {
974 Expression* arg = args->at(i); 989 Expression* arg = args->at(i);
975 RECURSE(VisitWithExpectation(arg, Type::Any(), 990 RECURSE(VisitWithExpectation(arg, Type::Any(),
976 "foreign call argument expected to be any")); 991 "foreign call argument expected to be any"));
992 // Checking for asm extern types explicitly, as the type system
993 // doesn't correctly check their inheritance relationship.
994 if (!computed_type_->Is(cache_.kAsmSigned) &&
995 !computed_type_->Is(cache_.kAsmFixnum) &&
996 !computed_type_->Is(cache_.kAsmDouble)) {
997 FAIL(arg,
998 "foreign call argument expected to be int, double, or fixnum");
999 }
977 } 1000 }
978 intish_ = kMaxUncombinedAdditiveSteps; 1001 intish_ = kMaxUncombinedAdditiveSteps;
979 IntersectResult(expr, Type::Number()); 1002 IntersectResult(expr, expected_type);
980 } else { 1003 } else {
981 FAIL(expr, "invalid callee"); 1004 FAIL(expr, "invalid callee");
982 } 1005 }
983 } 1006 }
984 1007
985 1008
986 void AsmTyper::VisitCallNew(CallNew* expr) { 1009 void AsmTyper::VisitCallNew(CallNew* expr) {
987 if (in_function_) { 1010 if (in_function_) {
988 FAIL(expr, "new not allowed in module function"); 1011 FAIL(expr, "new not allowed in module function");
989 } 1012 }
(...skipping 17 matching lines...) Expand all
1007 FAIL(expr, "ill-typed new operator"); 1030 FAIL(expr, "ill-typed new operator");
1008 } 1031 }
1009 1032
1010 1033
1011 void AsmTyper::VisitCallRuntime(CallRuntime* expr) { 1034 void AsmTyper::VisitCallRuntime(CallRuntime* expr) {
1012 // Allow runtime calls for now. 1035 // Allow runtime calls for now.
1013 } 1036 }
1014 1037
1015 1038
1016 void AsmTyper::VisitUnaryOperation(UnaryOperation* expr) { 1039 void AsmTyper::VisitUnaryOperation(UnaryOperation* expr) {
1040 if (!in_function_) {
1041 FAIL(expr, "unary operator inside module body");
1042 }
1017 switch (expr->op()) { 1043 switch (expr->op()) {
1018 case Token::NOT: // Used to encode != and !== 1044 case Token::NOT: // Used to encode != and !==
1019 RECURSE(VisitWithExpectation(expr->expression(), cache_.kAsmInt, 1045 RECURSE(VisitWithExpectation(expr->expression(), cache_.kAsmInt,
1020 "operand expected to be integer")); 1046 "operand expected to be integer"));
1021 IntersectResult(expr, cache_.kAsmSigned); 1047 IntersectResult(expr, cache_.kAsmSigned);
1022 return; 1048 return;
1023 case Token::DELETE: 1049 case Token::DELETE:
1024 FAIL(expr, "delete operator encountered"); 1050 FAIL(expr, "delete operator encountered");
1025 case Token::VOID: 1051 case Token::VOID:
1026 FAIL(expr, "void operator encountered"); 1052 FAIL(expr, "void operator encountered");
1027 case Token::TYPEOF: 1053 case Token::TYPEOF:
1028 FAIL(expr, "typeof operator encountered"); 1054 FAIL(expr, "typeof operator encountered");
1029 default: 1055 default:
1030 UNREACHABLE(); 1056 UNREACHABLE();
1031 } 1057 }
1032 } 1058 }
1033 1059
1034 1060
1035 void AsmTyper::VisitCountOperation(CountOperation* expr) { 1061 void AsmTyper::VisitCountOperation(CountOperation* expr) {
1036 FAIL(expr, "increment or decrement operator encountered"); 1062 FAIL(expr, "increment or decrement operator encountered");
1037 } 1063 }
1038 1064
1039 1065
1040 void AsmTyper::VisitIntegerBitwiseOperator(BinaryOperation* expr, 1066 void AsmTyper::VisitIntegerBitwiseOperator(BinaryOperation* expr,
1041 Type* left_expected, 1067 Type* left_expected,
1042 Type* right_expected, 1068 Type* right_expected,
1043 Type* result_type, bool conversion) { 1069 Type* result_type, bool conversion) {
1044 RECURSE(VisitWithExpectation(expr->left(), Type::Number(), 1070 RECURSE(VisitWithExpectation(expr->left(), Type::Number(zone()),
1045 "left bitwise operand expected to be a number")); 1071 "left bitwise operand expected to be a number"));
1046 int left_intish = intish_; 1072 int left_intish = intish_;
1047 Type* left_type = computed_type_; 1073 Type* left_type = computed_type_;
1048 if (!left_type->Is(left_expected)) { 1074 if (!left_type->Is(left_expected)) {
1049 FAIL(expr->left(), "left bitwise operand expected to be an integer"); 1075 FAIL(expr->left(), "left bitwise operand expected to be an integer");
1050 } 1076 }
1051 if (left_intish > kMaxUncombinedAdditiveSteps) { 1077 if (left_intish > kMaxUncombinedAdditiveSteps) {
1052 FAIL(expr->left(), "too many consecutive additive ops"); 1078 FAIL(expr->left(), "too many consecutive additive ops");
1053 } 1079 }
1054 1080
(...skipping 20 matching lines...) Expand all
1075 if (!conversion) { 1101 if (!conversion) {
1076 if (!left_type->Is(right_type) || !right_type->Is(left_type)) { 1102 if (!left_type->Is(right_type) || !right_type->Is(left_type)) {
1077 FAIL(expr, "ill-typed bitwise operation"); 1103 FAIL(expr, "ill-typed bitwise operation");
1078 } 1104 }
1079 } 1105 }
1080 IntersectResult(expr, result_type); 1106 IntersectResult(expr, result_type);
1081 } 1107 }
1082 1108
1083 1109
1084 void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) { 1110 void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) {
1111 if (!in_function_) {
1112 if (expr->op() != Token::BIT_OR && expr->op() != Token::MUL) {
1113 FAIL(expr, "illegal binary operator inside module body");
1114 }
1115 if (!(expr->left()->IsProperty() || expr->left()->IsVariableProxy()) ||
1116 !expr->right()->IsLiteral()) {
1117 FAIL(expr, "illegal computation inside module body");
1118 }
1119 }
1085 switch (expr->op()) { 1120 switch (expr->op()) {
1086 case Token::COMMA: { 1121 case Token::COMMA: {
1087 RECURSE(VisitWithExpectation(expr->left(), Type::Any(), 1122 RECURSE(VisitWithExpectation(expr->left(), Type::Any(),
1088 "left comma operand expected to be any")); 1123 "left comma operand expected to be any"));
1089 RECURSE(VisitWithExpectation(expr->right(), Type::Any(), 1124 RECURSE(VisitWithExpectation(expr->right(), Type::Any(),
1090 "right comma operand expected to be any")); 1125 "right comma operand expected to be any"));
1091 IntersectResult(expr, computed_type_); 1126 IntersectResult(expr, computed_type_);
1092 return; 1127 return;
1093 } 1128 }
1094 case Token::OR: 1129 case Token::OR:
1095 case Token::AND: 1130 case Token::AND:
1096 FAIL(expr, "illegal logical operator"); 1131 FAIL(expr, "illegal logical operator");
1097 case Token::BIT_OR: { 1132 case Token::BIT_OR: {
1098 // BIT_OR allows Any since it is used as a type coercion. 1133 // BIT_OR allows Any since it is used as a type coercion.
1099 VisitIntegerBitwiseOperator(expr, Type::Any(), cache_.kAsmInt, 1134 VisitIntegerBitwiseOperator(expr, Type::Any(), cache_.kAsmInt,
1100 cache_.kAsmSigned, true); 1135 cache_.kAsmSigned, true);
1136 if (expr->left()->IsCall() && expr->op() == Token::BIT_OR) {
1137 IntersectResult(expr->left(), cache_.kAsmSigned);
1138 }
1101 return; 1139 return;
1102 } 1140 }
1103 case Token::BIT_XOR: { 1141 case Token::BIT_XOR: {
1104 // Handle booleans specially to handle de-sugared ! 1142 // Handle booleans specially to handle de-sugared !
1105 Literal* left = expr->left()->AsLiteral(); 1143 Literal* left = expr->left()->AsLiteral();
1106 if (left && left->value()->IsBoolean()) { 1144 if (left && left->value()->IsBoolean()) {
1107 if (left->ToBooleanIsTrue()) { 1145 if (left->ToBooleanIsTrue()) {
1108 left->set_bounds(Bounds(cache_.kSingletonOne)); 1146 left->set_bounds(Bounds(cache_.kSingletonOne));
1109 RECURSE(VisitWithExpectation(expr->right(), cache_.kAsmInt, 1147 RECURSE(VisitWithExpectation(expr->right(), cache_.kAsmInt,
1110 "not operator expects an integer")); 1148 "not operator expects an integer"));
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 if (intish_ > kMaxUncombinedMultiplicativeSteps) { 1215 if (intish_ > kMaxUncombinedMultiplicativeSteps) {
1178 FAIL(expr, "too many consecutive multiplicative ops"); 1216 FAIL(expr, "too many consecutive multiplicative ops");
1179 } 1217 }
1180 } 1218 }
1181 IntersectResult(expr, cache_.kAsmInt); 1219 IntersectResult(expr, cache_.kAsmInt);
1182 return; 1220 return;
1183 } 1221 }
1184 } else if (expr->op() == Token::MUL && expr->right()->IsLiteral() && 1222 } else if (expr->op() == Token::MUL && expr->right()->IsLiteral() &&
1185 right_type->Is(cache_.kAsmDouble)) { 1223 right_type->Is(cache_.kAsmDouble)) {
1186 // For unary +, expressed as x * 1.0 1224 // For unary +, expressed as x * 1.0
1225 if (expr->left()->IsCall() && expr->op() == Token::MUL) {
1226 IntersectResult(expr->left(), cache_.kAsmDouble);
1227 }
1187 IntersectResult(expr, cache_.kAsmDouble); 1228 IntersectResult(expr, cache_.kAsmDouble);
1188 return; 1229 return;
1189 } else if (type->Is(cache_.kAsmFloat) && expr->op() != Token::MOD) { 1230 } else if (type->Is(cache_.kAsmFloat) && expr->op() != Token::MOD) {
1190 if (left_intish != 0 || right_intish != 0) { 1231 if (left_intish != 0 || right_intish != 0) {
1191 FAIL(expr, "float operation before required fround"); 1232 FAIL(expr, "float operation before required fround");
1192 } 1233 }
1193 IntersectResult(expr, cache_.kAsmFloat); 1234 IntersectResult(expr, cache_.kAsmFloat);
1194 intish_ = 1; 1235 intish_ = 1;
1195 return; 1236 return;
1196 } else if (type->Is(cache_.kAsmDouble)) { 1237 } else if (type->Is(cache_.kAsmDouble)) {
1197 IntersectResult(expr, cache_.kAsmDouble); 1238 IntersectResult(expr, cache_.kAsmDouble);
1198 return; 1239 return;
1199 } else { 1240 } else {
1200 FAIL(expr, "ill-typed arithmetic operation"); 1241 FAIL(expr, "ill-typed arithmetic operation");
1201 } 1242 }
1202 } 1243 }
1203 default: 1244 default:
1204 UNREACHABLE(); 1245 UNREACHABLE();
1205 } 1246 }
1206 } 1247 }
1207 1248
1208 1249
1209 void AsmTyper::VisitCompareOperation(CompareOperation* expr) { 1250 void AsmTyper::VisitCompareOperation(CompareOperation* expr) {
1251 if (!in_function_) {
1252 FAIL(expr, "comparison inside module body");
1253 }
1210 Token::Value op = expr->op(); 1254 Token::Value op = expr->op();
1211 if (op != Token::EQ && op != Token::NE && op != Token::LT && 1255 if (op != Token::EQ && op != Token::NE && op != Token::LT &&
1212 op != Token::LTE && op != Token::GT && op != Token::GTE) { 1256 op != Token::LTE && op != Token::GT && op != Token::GTE) {
1213 FAIL(expr, "illegal comparison operator"); 1257 FAIL(expr, "illegal comparison operator");
1214 } 1258 }
1215 1259
1216 RECURSE( 1260 RECURSE(
1217 VisitWithExpectation(expr->left(), Type::Number(), 1261 VisitWithExpectation(expr->left(), Type::Number(),
1218 "left comparison operand expected to be number")); 1262 "left comparison operand expected to be number"));
1219 Type* left_type = computed_type_; 1263 Type* left_type = computed_type_;
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
1486 1530
1487 1531
1488 void AsmTyper::VisitRewritableAssignmentExpression( 1532 void AsmTyper::VisitRewritableAssignmentExpression(
1489 RewritableAssignmentExpression* expr) { 1533 RewritableAssignmentExpression* expr) {
1490 RECURSE(Visit(expr->expression())); 1534 RECURSE(Visit(expr->expression()));
1491 } 1535 }
1492 1536
1493 1537
1494 } // namespace internal 1538 } // namespace internal
1495 } // namespace v8 1539 } // namespace v8
OLDNEW
« src/typing-asm.h ('K') | « src/typing-asm.h ('k') | test/cctest/test-asm-validator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698