OLD | NEW |
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/base/lazy-instance.h" | 8 #include "src/base/lazy-instance.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/compiler/common-operator.h" | 10 #include "src/compiler/common-operator.h" |
(...skipping 1355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1366 | 1366 |
1367 Type* Typer::Visitor::TypeJSYield(Node* node) { return Type::Any(); } | 1367 Type* Typer::Visitor::TypeJSYield(Node* node) { return Type::Any(); } |
1368 | 1368 |
1369 | 1369 |
1370 Type* Typer::Visitor::TypeJSCallConstruct(Node* node) { | 1370 Type* Typer::Visitor::TypeJSCallConstruct(Node* node) { |
1371 return Type::Receiver(); | 1371 return Type::Receiver(); |
1372 } | 1372 } |
1373 | 1373 |
1374 | 1374 |
1375 Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) { | 1375 Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) { |
1376 return fun->IsFunction() ? fun->AsFunction()->Result() : Type::Any(); | 1376 if (fun->IsFunction()) { |
| 1377 return fun->AsFunction()->Result(); |
| 1378 } |
| 1379 if (fun->IsConstant() && fun->AsConstant()->Value()->IsJSFunction()) { |
| 1380 Handle<JSFunction> function = |
| 1381 Handle<JSFunction>::cast(fun->AsConstant()->Value()); |
| 1382 if (function->shared()->HasBuiltinFunctionId()) { |
| 1383 switch (function->shared()->builtin_function_id()) { |
| 1384 case kMathRandom: |
| 1385 return Type::OrderedNumber(); |
| 1386 case kMathFloor: |
| 1387 case kMathRound: |
| 1388 case kMathCeil: |
| 1389 return t->cache_.kWeakint; |
| 1390 // Unary math functions. |
| 1391 case kMathAbs: |
| 1392 case kMathLog: |
| 1393 case kMathExp: |
| 1394 case kMathSqrt: |
| 1395 case kMathCos: |
| 1396 case kMathSin: |
| 1397 case kMathTan: |
| 1398 case kMathAcos: |
| 1399 case kMathAsin: |
| 1400 case kMathAtan: |
| 1401 case kMathFround: |
| 1402 return Type::Number(); |
| 1403 // Binary math functions. |
| 1404 case kMathAtan2: |
| 1405 case kMathPow: |
| 1406 case kMathMax: |
| 1407 case kMathMin: |
| 1408 return Type::Number(); |
| 1409 case kMathImul: |
| 1410 return Type::Signed32(); |
| 1411 case kMathClz32: |
| 1412 return t->cache_.kZeroToThirtyTwo; |
| 1413 // String functions. |
| 1414 case kStringCharAt: |
| 1415 case kStringFromCharCode: |
| 1416 return Type::String(); |
| 1417 // Array functions. |
| 1418 case kArrayIndexOf: |
| 1419 case kArrayLastIndexOf: |
| 1420 return Type::Number(); |
| 1421 default: |
| 1422 break; |
| 1423 } |
| 1424 } |
| 1425 } |
| 1426 return Type::Any(); |
1377 } | 1427 } |
1378 | 1428 |
1379 | 1429 |
1380 Type* Typer::Visitor::TypeJSCallFunction(Node* node) { | 1430 Type* Typer::Visitor::TypeJSCallFunction(Node* node) { |
1381 return TypeUnaryOp(node, JSCallFunctionTyper); // We ignore argument types. | 1431 // TODO(bmeurer): We could infer better types if we wouldn't ignore the |
| 1432 // argument types for the JSCallFunctionTyper above. |
| 1433 return TypeUnaryOp(node, JSCallFunctionTyper); |
1382 } | 1434 } |
1383 | 1435 |
1384 | 1436 |
1385 Type* Typer::Visitor::TypeJSCallRuntime(Node* node) { | 1437 Type* Typer::Visitor::TypeJSCallRuntime(Node* node) { |
1386 switch (CallRuntimeParametersOf(node->op()).id()) { | 1438 switch (CallRuntimeParametersOf(node->op()).id()) { |
1387 case Runtime::kInlineIsSmi: | 1439 case Runtime::kInlineIsSmi: |
1388 case Runtime::kInlineIsArray: | 1440 case Runtime::kInlineIsArray: |
1389 case Runtime::kInlineIsDate: | 1441 case Runtime::kInlineIsDate: |
1390 case Runtime::kInlineIsTypedArray: | 1442 case Runtime::kInlineIsTypedArray: |
1391 case Runtime::kInlineIsMinusZero: | 1443 case Runtime::kInlineIsMinusZero: |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2036 Type* Typer::Visitor::TypeCheckedStore(Node* node) { | 2088 Type* Typer::Visitor::TypeCheckedStore(Node* node) { |
2037 UNREACHABLE(); | 2089 UNREACHABLE(); |
2038 return nullptr; | 2090 return nullptr; |
2039 } | 2091 } |
2040 | 2092 |
2041 | 2093 |
2042 // Heap constants. | 2094 // Heap constants. |
2043 | 2095 |
2044 | 2096 |
2045 Type* Typer::Visitor::TypeConstant(Handle<Object> value) { | 2097 Type* Typer::Visitor::TypeConstant(Handle<Object> value) { |
2046 if (value->IsJSFunction()) { | 2098 if (value->IsJSTypedArray()) { |
2047 if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) { | |
2048 switch (JSFunction::cast(*value)->shared()->builtin_function_id()) { | |
2049 case kMathRandom: | |
2050 return typer_->cache_.kRandomFunc0; | |
2051 case kMathFloor: | |
2052 case kMathRound: | |
2053 case kMathCeil: | |
2054 return typer_->cache_.kWeakintFunc1; | |
2055 // Unary math functions. | |
2056 case kMathAbs: // TODO(rossberg): can't express overloading | |
2057 case kMathLog: | |
2058 case kMathExp: | |
2059 case kMathSqrt: | |
2060 case kMathCos: | |
2061 case kMathSin: | |
2062 case kMathTan: | |
2063 case kMathAcos: | |
2064 case kMathAsin: | |
2065 case kMathAtan: | |
2066 case kMathFround: | |
2067 return typer_->cache_.kNumberFunc1; | |
2068 // Binary math functions. | |
2069 case kMathAtan2: | |
2070 case kMathPow: | |
2071 case kMathMax: | |
2072 case kMathMin: | |
2073 return typer_->cache_.kNumberFunc2; | |
2074 case kMathImul: | |
2075 return typer_->cache_.kImulFunc; | |
2076 case kMathClz32: | |
2077 return typer_->cache_.kClz32Func; | |
2078 default: | |
2079 break; | |
2080 } | |
2081 } | |
2082 int const arity = | |
2083 JSFunction::cast(*value)->shared()->internal_formal_parameter_count(); | |
2084 switch (arity) { | |
2085 case SharedFunctionInfo::kDontAdaptArgumentsSentinel: | |
2086 // Some smart optimization at work... &%$!&@+$! | |
2087 break; | |
2088 case 0: | |
2089 return typer_->cache_.kAnyFunc0; | |
2090 case 1: | |
2091 return typer_->cache_.kAnyFunc1; | |
2092 case 2: | |
2093 return typer_->cache_.kAnyFunc2; | |
2094 case 3: | |
2095 return typer_->cache_.kAnyFunc3; | |
2096 default: { | |
2097 DCHECK_LT(3, arity); | |
2098 Type** const params = zone()->NewArray<Type*>(arity); | |
2099 std::fill(¶ms[0], ¶ms[arity], Type::Any(zone())); | |
2100 return Type::Function(Type::Any(zone()), arity, params, zone()); | |
2101 } | |
2102 } | |
2103 } else if (value->IsJSTypedArray()) { | |
2104 switch (JSTypedArray::cast(*value)->type()) { | 2099 switch (JSTypedArray::cast(*value)->type()) { |
2105 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 2100 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
2106 case kExternal##Type##Array: \ | 2101 case kExternal##Type##Array: \ |
2107 return typer_->cache_.k##Type##Array; | 2102 return typer_->cache_.k##Type##Array; |
2108 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 2103 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
2109 #undef TYPED_ARRAY_CASE | 2104 #undef TYPED_ARRAY_CASE |
2110 } | 2105 } |
2111 } | 2106 } |
2112 if (Type::IsInteger(*value)) { | 2107 if (Type::IsInteger(*value)) { |
2113 return Type::Range(value->Number(), value->Number(), zone()); | 2108 return Type::Range(value->Number(), value->Number(), zone()); |
2114 } | 2109 } |
2115 return Type::Constant(value, zone()); | 2110 return Type::Constant(value, zone()); |
2116 } | 2111 } |
2117 | 2112 |
2118 } // namespace compiler | 2113 } // namespace compiler |
2119 } // namespace internal | 2114 } // namespace internal |
2120 } // namespace v8 | 2115 } // namespace v8 |
OLD | NEW |