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

Side by Side Diff: src/compiler/typer.cc

Issue 2084943002: [turbofan] Reuse the operation typer's logic in the typer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Tweak + rebase Created 4 years, 6 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
« no previous file with comments | « src/compiler/typer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/compiler/typer.h" 5 #include "src/compiler/typer.h"
6 6
7 #include "src/base/flags.h" 7 #include "src/base/flags.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/compilation-dependencies.h" 9 #include "src/compilation-dependencies.h"
10 #include "src/compiler/common-operator.h" 10 #include "src/compiler/common-operator.h"
11 #include "src/compiler/graph-reducer.h" 11 #include "src/compiler/graph-reducer.h"
12 #include "src/compiler/js-operator.h" 12 #include "src/compiler/js-operator.h"
13 #include "src/compiler/node-properties.h"
13 #include "src/compiler/node.h" 14 #include "src/compiler/node.h"
14 #include "src/compiler/node-properties.h" 15 #include "src/compiler/operation-typer.h"
15 #include "src/compiler/simplified-operator.h" 16 #include "src/compiler/simplified-operator.h"
16 #include "src/objects-inl.h" 17 #include "src/objects-inl.h"
17 #include "src/type-cache.h" 18 #include "src/type-cache.h"
18 19
19 namespace v8 { 20 namespace v8 {
20 namespace internal { 21 namespace internal {
21 namespace compiler { 22 namespace compiler {
22 23
23 class Typer::Decorator final : public GraphDecorator { 24 class Typer::Decorator final : public GraphDecorator {
24 public: 25 public:
25 explicit Decorator(Typer* typer) : typer_(typer) {} 26 explicit Decorator(Typer* typer) : typer_(typer) {}
26 void Decorate(Node* node) final; 27 void Decorate(Node* node) final;
27 28
28 private: 29 private:
29 Typer* const typer_; 30 Typer* const typer_;
30 }; 31 };
31 32
32 Typer::Typer(Isolate* isolate, Graph* graph, Flags flags, 33 Typer::Typer(Isolate* isolate, Graph* graph, Flags flags,
33 CompilationDependencies* dependencies, FunctionType* function_type) 34 CompilationDependencies* dependencies, FunctionType* function_type)
34 : isolate_(isolate), 35 : isolate_(isolate),
35 graph_(graph), 36 graph_(graph),
36 flags_(flags), 37 flags_(flags),
37 dependencies_(dependencies), 38 dependencies_(dependencies),
38 function_type_(function_type), 39 function_type_(function_type),
39 decorator_(nullptr), 40 decorator_(nullptr),
40 cache_(TypeCache::Get()) { 41 cache_(TypeCache::Get()),
42 operation_typer_(isolate, zone()) {
41 Zone* zone = this->zone(); 43 Zone* zone = this->zone();
42 Factory* const factory = isolate->factory(); 44 Factory* const factory = isolate->factory();
43 45
44 Type* infinity = Type::Constant(factory->infinity_value(), zone); 46 Type* infinity = Type::Constant(factory->infinity_value(), zone);
45 Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone); 47 Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone);
46 // Unfortunately, the infinities created in other places might be different 48 // Unfortunately, the infinities created in other places might be different
47 // ones (eg the result of NewNumber in TypeNumberConstant). 49 // ones (eg the result of NewNumber in TypeNumberConstant).
48 Type* truncating_to_zero = 50 Type* truncating_to_zero =
49 Type::Union(Type::Union(infinity, minus_infinity, zone), 51 Type::Union(Type::Union(infinity, minus_infinity, zone),
50 Type::MinusZeroOrNaN(), zone); 52 Type::MinusZeroOrNaN(), zone);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 enum ComparisonOutcomeFlags { 227 enum ComparisonOutcomeFlags {
226 kComparisonTrue = 1, 228 kComparisonTrue = 1,
227 kComparisonFalse = 2, 229 kComparisonFalse = 2,
228 kComparisonUndefined = 4 230 kComparisonUndefined = 4
229 }; 231 };
230 typedef base::Flags<ComparisonOutcomeFlags> ComparisonOutcome; 232 typedef base::Flags<ComparisonOutcomeFlags> ComparisonOutcome;
231 233
232 static ComparisonOutcome Invert(ComparisonOutcome, Typer*); 234 static ComparisonOutcome Invert(ComparisonOutcome, Typer*);
233 static Type* Invert(Type*, Typer*); 235 static Type* Invert(Type*, Typer*);
234 static Type* FalsifyUndefined(ComparisonOutcome, Typer*); 236 static Type* FalsifyUndefined(ComparisonOutcome, Typer*);
235 static Type* Rangify(Type*, Typer*);
236 237
237 static Type* ToPrimitive(Type*, Typer*); 238 static Type* ToPrimitive(Type*, Typer*);
238 static Type* ToBoolean(Type*, Typer*); 239 static Type* ToBoolean(Type*, Typer*);
239 static Type* ToInteger(Type*, Typer*); 240 static Type* ToInteger(Type*, Typer*);
240 static Type* ToLength(Type*, Typer*); 241 static Type* ToLength(Type*, Typer*);
241 static Type* ToName(Type*, Typer*); 242 static Type* ToName(Type*, Typer*);
242 static Type* ToNumber(Type*, Typer*); 243 static Type* ToNumber(Type*, Typer*);
243 static Type* ToObject(Type*, Typer*); 244 static Type* ToObject(Type*, Typer*);
244 static Type* ToString(Type*, Typer*); 245 static Type* ToString(Type*, Typer*);
245 static Type* NumberCeil(Type*, Typer*); 246 static Type* NumberCeil(Type*, Typer*);
246 static Type* NumberFloor(Type*, Typer*); 247 static Type* NumberFloor(Type*, Typer*);
247 static Type* NumberRound(Type*, Typer*); 248 static Type* NumberRound(Type*, Typer*);
248 static Type* NumberTrunc(Type*, Typer*); 249 static Type* NumberTrunc(Type*, Typer*);
249 static Type* NumberToInt32(Type*, Typer*); 250 static Type* NumberToInt32(Type*, Typer*);
250 static Type* NumberToUint32(Type*, Typer*); 251 static Type* NumberToUint32(Type*, Typer*);
251 252
252 static Type* ObjectIsCallable(Type*, Typer*); 253 static Type* ObjectIsCallable(Type*, Typer*);
253 static Type* ObjectIsNumber(Type*, Typer*); 254 static Type* ObjectIsNumber(Type*, Typer*);
254 static Type* ObjectIsReceiver(Type*, Typer*); 255 static Type* ObjectIsReceiver(Type*, Typer*);
255 static Type* ObjectIsSmi(Type*, Typer*); 256 static Type* ObjectIsSmi(Type*, Typer*);
256 static Type* ObjectIsString(Type*, Typer*); 257 static Type* ObjectIsString(Type*, Typer*);
257 static Type* ObjectIsUndetectable(Type*, Typer*); 258 static Type* ObjectIsUndetectable(Type*, Typer*);
258 259
259 static Type* JSAddRanger(double lhs_min, double lhs_max, double rhs_min,
260 double rhs_max, Typer* t);
261 static Type* JSSubtractRanger(RangeType*, RangeType*, Typer*);
262 static Type* JSDivideRanger(RangeType*, RangeType*, Typer*);
263 static Type* JSModulusRanger(RangeType*, RangeType*, Typer*);
264
265 static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*); 260 static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*);
266 261
267 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*); 262 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*);
268 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) 263 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
269 #undef DECLARE_METHOD 264 #undef DECLARE_METHOD
270 265
271 static Type* JSTypeOfTyper(Type*, Typer*); 266 static Type* JSTypeOfTyper(Type*, Typer*);
272 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*); 267 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*);
273 static Type* JSCallFunctionTyper(Type*, Typer*); 268 static Type* JSCallFunctionTyper(Type*, Typer*);
274 269
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 if ((outcome & kComparisonFalse) != 0 || 370 if ((outcome & kComparisonFalse) != 0 ||
376 (outcome & kComparisonUndefined) != 0) { 371 (outcome & kComparisonUndefined) != 0) {
377 return (outcome & kComparisonTrue) != 0 ? Type::Boolean() 372 return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
378 : t->singleton_false_; 373 : t->singleton_false_;
379 } 374 }
380 // Type should be non empty, so we know it should be true. 375 // Type should be non empty, so we know it should be true.
381 DCHECK((outcome & kComparisonTrue) != 0); 376 DCHECK((outcome & kComparisonTrue) != 0);
382 return t->singleton_true_; 377 return t->singleton_true_;
383 } 378 }
384 379
385
386 Type* Typer::Visitor::Rangify(Type* type, Typer* t) {
387 if (type->IsRange()) return type; // Shortcut.
388 if (!type->Is(t->cache_.kInteger)) {
389 return type; // Give up on non-integer types.
390 }
391 double min = type->Min();
392 double max = type->Max();
393 // Handle the degenerate case of empty bitset types (such as
394 // OtherUnsigned31 and OtherSigned32 on 64-bit architectures).
395 if (std::isnan(min)) {
396 DCHECK(std::isnan(max));
397 return type;
398 }
399 return Type::Range(min, max, t->zone());
400 }
401
402
403 // Type conversion. 380 // Type conversion.
404 381
405
406 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) { 382 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) {
407 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { 383 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
408 return type; 384 return type;
409 } 385 }
410 return Type::Primitive(); 386 return Type::Primitive();
411 } 387 }
412 388
413 389
414 Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) { 390 Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) {
415 if (type->Is(Type::Boolean())) return type; 391 if (type->Is(Type::Boolean())) return type;
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 975
1000 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { 976 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) {
1001 lhs = NumberToUint32(ToNumber(lhs, t), t); 977 lhs = NumberToUint32(ToNumber(lhs, t), t);
1002 // Logical right-shifting any value cannot make it larger. 978 // Logical right-shifting any value cannot make it larger.
1003 return Type::Range(0.0, lhs->Max(), t->zone()); 979 return Type::Range(0.0, lhs->Max(), t->zone());
1004 } 980 }
1005 981
1006 982
1007 // JS arithmetic operators. 983 // JS arithmetic operators.
1008 984
1009
1010 // Returns the array's least element, ignoring NaN.
1011 // There must be at least one non-NaN element.
1012 // Any -0 is converted to 0.
1013 static double array_min(double a[], size_t n) {
1014 DCHECK(n != 0);
1015 double x = +V8_INFINITY;
1016 for (size_t i = 0; i < n; ++i) {
1017 if (!std::isnan(a[i])) {
1018 x = std::min(a[i], x);
1019 }
1020 }
1021 DCHECK(!std::isnan(x));
1022 return x == 0 ? 0 : x; // -0 -> 0
1023 }
1024
1025
1026 // Returns the array's greatest element, ignoring NaN.
1027 // There must be at least one non-NaN element.
1028 // Any -0 is converted to 0.
1029 static double array_max(double a[], size_t n) {
1030 DCHECK(n != 0);
1031 double x = -V8_INFINITY;
1032 for (size_t i = 0; i < n; ++i) {
1033 if (!std::isnan(a[i])) {
1034 x = std::max(a[i], x);
1035 }
1036 }
1037 DCHECK(!std::isnan(x));
1038 return x == 0 ? 0 : x; // -0 -> 0
1039 }
1040
1041 Type* Typer::Visitor::JSAddRanger(double lhs_min, double lhs_max,
1042 double rhs_min, double rhs_max, Typer* t) {
1043 double results[4];
1044 results[0] = lhs_min + rhs_min;
1045 results[1] = lhs_min + rhs_max;
1046 results[2] = lhs_max + rhs_min;
1047 results[3] = lhs_max + rhs_max;
1048 // The results can be nan (the sum of two infinities of opposite sign).
1049 // On the other hand, if none of the "results" above is nan, then the actual
1050 // result cannot be nan either.
1051 int nans = 0;
1052 for (int i = 0; i < 4; ++i) {
1053 if (std::isnan(results[i])) ++nans;
1054 }
1055 if (nans == 4) return Type::NaN(); // [-inf..-inf] + [inf..inf] or vice versa
1056 Type* range =
1057 Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
1058 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone());
1059 // Examples:
1060 // [-inf, -inf] + [+inf, +inf] = NaN
1061 // [-inf, -inf] + [n, +inf] = [-inf, -inf] \/ NaN
1062 // [-inf, +inf] + [n, +inf] = [-inf, +inf] \/ NaN
1063 // [-inf, m] + [n, +inf] = [-inf, +inf] \/ NaN
1064 }
1065
1066
1067 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { 985 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
1068 lhs = ToPrimitive(lhs, t); 986 lhs = ToPrimitive(lhs, t);
1069 rhs = ToPrimitive(rhs, t); 987 rhs = ToPrimitive(rhs, t);
1070 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { 988 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) {
1071 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { 989 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) {
1072 return Type::String(); 990 return Type::String();
1073 } else { 991 } else {
1074 return Type::NumberOrString(); 992 return Type::NumberOrString();
1075 } 993 }
1076 } 994 }
1077 // The addition must be numeric. 995 // The addition must be numeric.
1078 lhs = ToNumber(lhs, t); 996 return t->operation_typer()->NumericAdd(ToNumber(lhs, t), ToNumber(rhs, t));
1079 rhs = ToNumber(rhs, t);
1080 // We can give more precise types for integers.
1081 if (!lhs->Is(t->cache_.kIntegerOrMinusZeroOrNaN) ||
1082 !rhs->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) {
1083 return Type::Number();
1084 }
1085 Type* int_lhs = Type::Intersect(lhs, t->cache_.kInteger, t->zone());
1086 Type* int_rhs = Type::Intersect(rhs, t->cache_.kInteger, t->zone());
1087 Type* result = JSAddRanger(int_lhs->Min(), int_lhs->Max(), int_rhs->Min(),
1088 int_rhs->Max(), t);
1089 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
1090 result = Type::Union(result, Type::NaN(), t->zone());
1091 }
1092 if (lhs->Maybe(Type::MinusZero()) && rhs->Maybe(Type::MinusZero())) {
1093 result = Type::Union(result, Type::MinusZero(), t->zone());
1094 }
1095 return result;
1096 } 997 }
1097 998
1098 Type* Typer::Visitor::JSSubtractRanger(RangeType* lhs, RangeType* rhs, 999 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) {
1099 Typer* t) { 1000 return t->operation_typer()->NumericSubtract(ToNumber(lhs, t),
1100 double results[4]; 1001 ToNumber(rhs, t));
1101 results[0] = lhs->Min() - rhs->Min();
1102 results[1] = lhs->Min() - rhs->Max();
1103 results[2] = lhs->Max() - rhs->Min();
1104 results[3] = lhs->Max() - rhs->Max();
1105 // Since none of the inputs can be -0, the result cannot be -0.
1106 // However, it can be nan (the subtraction of two infinities of same sign).
1107 // On the other hand, if none of the "results" above is nan, then the actual
1108 // result cannot be nan either.
1109 int nans = 0;
1110 for (int i = 0; i < 4; ++i) {
1111 if (std::isnan(results[i])) ++nans;
1112 }
1113 if (nans == 4) return Type::NaN(); // [inf..inf] - [inf..inf] (all same sign)
1114 Type* range =
1115 Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
1116 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone());
1117 // Examples:
1118 // [-inf, +inf] - [-inf, +inf] = [-inf, +inf] \/ NaN
1119 // [-inf, -inf] - [-inf, -inf] = NaN
1120 // [-inf, -inf] - [n, +inf] = [-inf, -inf] \/ NaN
1121 // [m, +inf] - [-inf, n] = [-inf, +inf] \/ NaN
1122 } 1002 }
1123 1003
1124 1004 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) {
1125 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { 1005 return t->operation_typer()->NumericMultiply(ToNumber(lhs, t),
1126 lhs = Rangify(ToNumber(lhs, t), t); 1006 ToNumber(rhs, t));
1127 rhs = Rangify(ToNumber(rhs, t), t);
1128 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
1129 if (lhs->IsRange() && rhs->IsRange()) {
1130 return JSSubtractRanger(lhs->AsRange(), rhs->AsRange(), t);
1131 }
1132 return Type::Number();
1133 } 1007 }
1134 1008
1135
1136 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) {
1137 lhs = Rangify(ToNumber(lhs, t), t);
1138 rhs = Rangify(ToNumber(rhs, t), t);
1139 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
1140 if (lhs->IsRange() && rhs->IsRange()) {
1141 double results[4];
1142 double lmin = lhs->AsRange()->Min();
1143 double lmax = lhs->AsRange()->Max();
1144 double rmin = rhs->AsRange()->Min();
1145 double rmax = rhs->AsRange()->Max();
1146 results[0] = lmin * rmin;
1147 results[1] = lmin * rmax;
1148 results[2] = lmax * rmin;
1149 results[3] = lmax * rmax;
1150 // If the result may be nan, we give up on calculating a precise type,
1151 // because
1152 // the discontinuity makes it too complicated. Note that even if none of
1153 // the
1154 // "results" above is nan, the actual result may still be, so we have to do
1155 // a
1156 // different check:
1157 bool maybe_nan = (lhs->Maybe(t->cache_.kSingletonZero) &&
1158 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
1159 (rhs->Maybe(t->cache_.kSingletonZero) &&
1160 (lmin == -V8_INFINITY || lmax == +V8_INFINITY));
1161 if (maybe_nan) return t->cache_.kIntegerOrMinusZeroOrNaN; // Giving up.
1162 bool maybe_minuszero = (lhs->Maybe(t->cache_.kSingletonZero) && rmin < 0) ||
1163 (rhs->Maybe(t->cache_.kSingletonZero) && lmin < 0);
1164 Type* range =
1165 Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
1166 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone())
1167 : range;
1168 }
1169 return Type::Number();
1170 }
1171
1172
1173 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { 1009 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
1010 return t->operation_typer()->NumericDivide(ToNumber(lhs, t),
1011 ToNumber(rhs, t));
1174 lhs = ToNumber(lhs, t); 1012 lhs = ToNumber(lhs, t);
1175 rhs = ToNumber(rhs, t); 1013 rhs = ToNumber(rhs, t);
1176 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 1014 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
1177 // Division is tricky, so all we do is try ruling out nan. 1015 // Division is tricky, so all we do is try ruling out nan.
1178 bool maybe_nan = 1016 bool maybe_nan =
1179 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) || 1017 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) ||
1180 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && 1018 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
1181 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); 1019 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
1182 return maybe_nan ? Type::Number() : Type::OrderedNumber(); 1020 return maybe_nan ? Type::Number() : Type::OrderedNumber();
1183 } 1021 }
1184 1022
1185 Type* Typer::Visitor::JSModulusRanger(RangeType* lhs, RangeType* rhs, 1023 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
1186 Typer* t) { 1024 return t->operation_typer()->NumericModulus(ToNumber(lhs, t),
1187 double lmin = lhs->Min(); 1025 ToNumber(rhs, t));
1188 double lmax = lhs->Max();
1189 double rmin = rhs->Min();
1190 double rmax = rhs->Max();
1191
1192 double labs = std::max(std::abs(lmin), std::abs(lmax));
1193 double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1;
1194 double abs = std::min(labs, rabs);
1195 bool maybe_minus_zero = false;
1196 double omin = 0;
1197 double omax = 0;
1198 if (lmin >= 0) { // {lhs} positive.
1199 omin = 0;
1200 omax = abs;
1201 } else if (lmax <= 0) { // {lhs} negative.
1202 omin = 0 - abs;
1203 omax = 0;
1204 maybe_minus_zero = true;
1205 } else {
1206 omin = 0 - abs;
1207 omax = abs;
1208 maybe_minus_zero = true;
1209 }
1210
1211 Type* result = Type::Range(omin, omax, t->zone());
1212 if (maybe_minus_zero)
1213 result = Type::Union(result, Type::MinusZero(), t->zone());
1214 return result;
1215 } 1026 }
1216 1027
1217 1028
1218 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
1219 lhs = ToNumber(lhs, t);
1220 rhs = ToNumber(rhs, t);
1221 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
1222
1223 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) ||
1224 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) {
1225 // Result maybe NaN.
1226 return Type::Number();
1227 }
1228
1229 lhs = Rangify(lhs, t);
1230 rhs = Rangify(rhs, t);
1231 if (lhs->IsRange() && rhs->IsRange()) {
1232 return JSModulusRanger(lhs->AsRange(), rhs->AsRange(), t);
1233 }
1234 return Type::OrderedNumber();
1235 }
1236
1237
1238 // JS unary operators. 1029 // JS unary operators.
1239 1030
1240 1031
1241 Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) { 1032 Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) {
1242 Factory* const f = t->isolate()->factory(); 1033 Factory* const f = t->isolate()->factory();
1243 if (type->Is(Type::Boolean())) { 1034 if (type->Is(Type::Boolean())) {
1244 return Type::Constant(f->boolean_string(), t->zone()); 1035 return Type::Constant(f->boolean_string(), t->zone());
1245 } else if (type->Is(Type::Number())) { 1036 } else if (type->Is(Type::Number())) {
1246 return Type::Constant(f->number_string(), t->zone()); 1037 return Type::Constant(f->number_string(), t->zone());
1247 } else if (type->Is(Type::String())) { 1038 } else if (type->Is(Type::String())) {
(...skipping 1549 matching lines...) Expand 10 before | Expand all | Expand 10 after
2797 } 2588 }
2798 if (Type::IsInteger(*value)) { 2589 if (Type::IsInteger(*value)) {
2799 return Type::Range(value->Number(), value->Number(), zone()); 2590 return Type::Range(value->Number(), value->Number(), zone());
2800 } 2591 }
2801 return Type::Constant(value, zone()); 2592 return Type::Constant(value, zone());
2802 } 2593 }
2803 2594
2804 } // namespace compiler 2595 } // namespace compiler
2805 } // namespace internal 2596 } // namespace internal
2806 } // namespace v8 2597 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/typer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698