aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/typer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/typer.cc')
-rw-r--r--src/compiler/typer.cc229
1 files changed, 208 insertions, 21 deletions
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index 2642a100..ed1a04aa 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -43,13 +43,14 @@ Typer::Typer(Isolate* isolate, Flags flags, Graph* graph)
Zone* zone = this->zone();
Factory* const factory = isolate->factory();
- singleton_false_ = Type::HeapConstant(factory->false_value(), zone);
- singleton_true_ = Type::HeapConstant(factory->true_value(), zone);
- singleton_the_hole_ = Type::HeapConstant(factory->the_hole_value(), zone);
+ singleton_empty_string_ = Type::HeapConstant(factory->empty_string(), zone);
+ singleton_false_ = operation_typer_.singleton_false();
+ singleton_true_ = operation_typer_.singleton_true();
falsish_ = Type::Union(
Type::Undetectable(),
Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone),
- singleton_the_hole_, zone),
+ Type::Union(singleton_empty_string_, Type::Hole(), zone),
+ zone),
zone);
truish_ = Type::Union(
singleton_true_,
@@ -122,6 +123,8 @@ class Typer::Visitor : public Reducer {
DECLARE_CASE(Deoptimize)
DECLARE_CASE(DeoptimizeIf)
DECLARE_CASE(DeoptimizeUnless)
+ DECLARE_CASE(TrapIf)
+ DECLARE_CASE(TrapUnless)
DECLARE_CASE(Return)
DECLARE_CASE(TailCall)
DECLARE_CASE(Terminate)
@@ -185,6 +188,8 @@ class Typer::Visitor : public Reducer {
DECLARE_CASE(Deoptimize)
DECLARE_CASE(DeoptimizeIf)
DECLARE_CASE(DeoptimizeUnless)
+ DECLARE_CASE(TrapIf)
+ DECLARE_CASE(TrapUnless)
DECLARE_CASE(Return)
DECLARE_CASE(TailCall)
DECLARE_CASE(Terminate)
@@ -279,7 +284,8 @@ class Typer::Visitor : public Reducer {
SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_METHOD)
#undef DECLARE_METHOD
- static Type* ObjectIsCallable(Type*, Typer*);
+ static Type* ObjectIsDetectableCallable(Type*, Typer*);
+ static Type* ObjectIsNonCallable(Type*, Typer*);
static Type* ObjectIsNumber(Type*, Typer*);
static Type* ObjectIsReceiver(Type*, Typer*);
static Type* ObjectIsSmi(Type*, Typer*);
@@ -292,7 +298,7 @@ class Typer::Visitor : public Reducer {
JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
#undef DECLARE_METHOD
- static Type* JSCallFunctionTyper(Type*, Typer*);
+ static Type* JSCallTyper(Type*, Typer*);
static Type* ReferenceEqualTyper(Type*, Type*, Typer*);
static Type* StringFromCharCodeTyper(Type*, Typer*);
@@ -497,9 +503,15 @@ Type* Typer::Visitor::ToString(Type* type, Typer* t) {
// Type checks.
-Type* Typer::Visitor::ObjectIsCallable(Type* type, Typer* t) {
- if (type->Is(Type::Function())) return t->singleton_true_;
- if (type->Is(Type::Primitive())) return t->singleton_false_;
+Type* Typer::Visitor::ObjectIsDetectableCallable(Type* type, Typer* t) {
+ if (type->Is(Type::DetectableCallable())) return t->singleton_true_;
+ if (!type->Maybe(Type::DetectableCallable())) return t->singleton_false_;
+ return Type::Boolean();
+}
+
+Type* Typer::Visitor::ObjectIsNonCallable(Type* type, Typer* t) {
+ if (type->Is(Type::NonCallable())) return t->singleton_true_;
+ if (!type->Maybe(Type::NonCallable())) return t->singleton_false_;
return Type::Boolean();
}
@@ -822,6 +834,10 @@ Type* Typer::Visitor::TypeTypedStateValues(Node* node) {
return Type::Internal();
}
+Type* Typer::Visitor::TypeArgumentsObjectState(Node* node) {
+ return Type::Internal();
+}
+
Type* Typer::Visitor::TypeObjectState(Node* node) { return Type::Internal(); }
Type* Typer::Visitor::TypeTypedObjectState(Node* node) {
@@ -893,8 +909,7 @@ Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) {
(lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
return t->singleton_false_;
}
- if ((lhs->Is(t->singleton_the_hole_) || rhs->Is(t->singleton_the_hole_)) &&
- !lhs->Maybe(rhs)) {
+ if ((lhs->Is(Type::Hole()) || rhs->Is(Type::Hole())) && !lhs->Maybe(rhs)) {
return t->singleton_false_;
}
if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
@@ -1041,6 +1056,9 @@ Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
// JS unary operators.
+Type* Typer::Visitor::TypeJSClassOf(Node* node) {
+ return Type::InternalizedStringOrNull();
+}
Type* Typer::Visitor::TypeJSTypeOf(Node* node) {
return Type::InternalizedString();
@@ -1233,6 +1251,15 @@ Type* Typer::Visitor::TypeJSStoreGlobal(Node* node) {
return nullptr;
}
+Type* Typer::Visitor::TypeJSStoreNamedOwn(Node* node) {
+ UNREACHABLE();
+ return nullptr;
+}
+
+Type* Typer::Visitor::TypeJSStoreDataPropertyInLiteral(Node* node) {
+ UNREACHABLE();
+ return nullptr;
+}
Type* Typer::Visitor::TypeJSDeleteProperty(Node* node) {
return Type::Boolean();
@@ -1240,12 +1267,21 @@ Type* Typer::Visitor::TypeJSDeleteProperty(Node* node) {
Type* Typer::Visitor::TypeJSHasProperty(Node* node) { return Type::Boolean(); }
-Type* Typer::Visitor::TypeJSInstanceOf(Node* node) { return Type::Boolean(); }
+// JS instanceof operator.
-Type* Typer::Visitor::TypeJSOrdinaryHasInstance(Node* node) {
+Type* Typer::Visitor::JSInstanceOfTyper(Type* lhs, Type* rhs, Typer* t) {
return Type::Boolean();
}
+Type* Typer::Visitor::JSOrdinaryHasInstanceTyper(Type* lhs, Type* rhs,
+ Typer* t) {
+ return Type::Boolean();
+}
+
+Type* Typer::Visitor::TypeJSGetSuperConstructor(Node* node) {
+ return Type::Callable();
+}
+
// JS context operators.
@@ -1291,12 +1327,13 @@ Type* Typer::Visitor::TypeJSCreateScriptContext(Node* node) {
// JS other operators.
+Type* Typer::Visitor::TypeJSConstruct(Node* node) { return Type::Receiver(); }
-Type* Typer::Visitor::TypeJSCallConstruct(Node* node) {
+Type* Typer::Visitor::TypeJSConstructWithSpread(Node* node) {
return Type::Receiver();
}
-Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
+Type* Typer::Visitor::JSCallTyper(Type* fun, Typer* t) {
if (fun->IsHeapConstant() && fun->AsHeapConstant()->Value()->IsJSFunction()) {
Handle<JSFunction> function =
Handle<JSFunction>::cast(fun->AsHeapConstant()->Value());
@@ -1344,6 +1381,8 @@ Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
case kMathClz32:
return t->cache_.kZeroToThirtyTwo;
// Date functions.
+ case kDateNow:
+ return t->cache_.kTimeValueType;
case kDateGetDate:
return t->cache_.kJSDateDayType;
case kDateGetDay:
@@ -1363,6 +1402,7 @@ Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
return t->cache_.kJSDateSecondType;
case kDateGetTime:
return t->cache_.kJSDateValueType;
+
// Number functions.
case kNumberIsFinite:
case kNumberIsInteger:
@@ -1375,16 +1415,41 @@ Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
return t->cache_.kIntegerOrMinusZeroOrNaN;
case kNumberToString:
return Type::String();
+
// String functions.
case kStringCharCodeAt:
return Type::Union(Type::Range(0, kMaxUInt16, t->zone()), Type::NaN(),
t->zone());
case kStringCharAt:
+ return Type::String();
+ case kStringCodePointAt:
+ return Type::Union(Type::Range(0.0, String::kMaxCodePoint, t->zone()),
+ Type::Undefined(), t->zone());
case kStringConcat:
case kStringFromCharCode:
+ case kStringFromCodePoint:
+ return Type::String();
+ case kStringIndexOf:
+ case kStringLastIndexOf:
+ return Type::Range(-1.0, String::kMaxLength - 1.0, t->zone());
+ case kStringEndsWith:
+ case kStringIncludes:
+ return Type::Boolean();
+ case kStringRaw:
+ case kStringRepeat:
+ case kStringSlice:
+ return Type::String();
+ case kStringStartsWith:
+ return Type::Boolean();
case kStringSubstr:
+ case kStringSubstring:
case kStringToLowerCase:
+ case kStringToString:
case kStringToUpperCase:
+ case kStringTrim:
+ case kStringTrimLeft:
+ case kStringTrimRight:
+ case kStringValueOf:
return Type::String();
case kStringIterator:
@@ -1401,15 +1466,59 @@ Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
return Type::OtherObject();
// Array functions.
+ case kArrayIsArray:
+ return Type::Boolean();
+ case kArrayConcat:
+ return Type::Receiver();
+ case kArrayEvery:
+ return Type::Boolean();
+ case kArrayFill:
+ case kArrayFilter:
+ return Type::Receiver();
+ case kArrayFindIndex:
+ return Type::Range(-1, kMaxSafeInteger, t->zone());
+ case kArrayForEach:
+ return Type::Undefined();
+ case kArrayIncludes:
+ return Type::Boolean();
case kArrayIndexOf:
+ return Type::Range(-1, kMaxSafeInteger, t->zone());
+ case kArrayJoin:
+ return Type::String();
case kArrayLastIndexOf:
return Type::Range(-1, kMaxSafeInteger, t->zone());
+ case kArrayMap:
+ return Type::Receiver();
case kArrayPush:
return t->cache_.kPositiveSafeInteger;
+ case kArrayReverse:
+ case kArraySlice:
+ return Type::Receiver();
+ case kArraySome:
+ return Type::Boolean();
+ case kArraySplice:
+ return Type::Receiver();
+ case kArrayUnshift:
+ return t->cache_.kPositiveSafeInteger;
// Object functions.
+ case kObjectAssign:
+ case kObjectCreate:
+ return Type::OtherObject();
case kObjectHasOwnProperty:
return Type::Boolean();
+ case kObjectToString:
+ return Type::String();
+
+ // RegExp functions.
+ case kRegExpCompile:
+ return Type::OtherObject();
+ case kRegExpExec:
+ return Type::Union(Type::OtherObject(), Type::Null(), t->zone());
+ case kRegExpTest:
+ return Type::Boolean();
+ case kRegExpToString:
+ return Type::String();
// Function functions.
case kFunctionHasInstance:
@@ -1426,6 +1535,46 @@ Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
case kGlobalIsFinite:
case kGlobalIsNaN:
return Type::Boolean();
+
+ // Map functions.
+ case kMapClear:
+ case kMapForEach:
+ return Type::Undefined();
+ case kMapDelete:
+ case kMapHas:
+ return Type::Boolean();
+ case kMapEntries:
+ case kMapKeys:
+ case kMapSet:
+ case kMapValues:
+ return Type::OtherObject();
+
+ // Set functions.
+ case kSetAdd:
+ case kSetEntries:
+ case kSetKeys:
+ case kSetValues:
+ return Type::OtherObject();
+ case kSetClear:
+ case kSetForEach:
+ return Type::Undefined();
+ case kSetDelete:
+ case kSetHas:
+ return Type::Boolean();
+
+ // WeakMap functions.
+ case kWeakMapDelete:
+ case kWeakMapHas:
+ return Type::Boolean();
+ case kWeakMapSet:
+ return Type::OtherObject();
+
+ // WeakSet functions.
+ case kWeakSetAdd:
+ return Type::OtherObject();
+ case kWeakSetDelete:
+ case kWeakSetHas:
+ return Type::Boolean();
default:
break;
}
@@ -1434,13 +1583,19 @@ Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
return Type::NonInternal();
}
+Type* Typer::Visitor::TypeJSCallForwardVarargs(Node* node) {
+ return TypeUnaryOp(node, JSCallTyper);
+}
-Type* Typer::Visitor::TypeJSCallFunction(Node* node) {
+Type* Typer::Visitor::TypeJSCall(Node* node) {
// TODO(bmeurer): We could infer better types if we wouldn't ignore the
- // argument types for the JSCallFunctionTyper above.
- return TypeUnaryOp(node, JSCallFunctionTyper);
+ // argument types for the JSCallTyper above.
+ return TypeUnaryOp(node, JSCallTyper);
}
+Type* Typer::Visitor::TypeJSCallWithSpread(Node* node) {
+ return TypeUnaryOp(node, JSCallTyper);
+}
Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
switch (CallRuntimeParametersOf(node->op()).id()) {
@@ -1468,6 +1623,8 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
return TypeUnaryOp(node, ToObject);
case Runtime::kInlineToString:
return TypeUnaryOp(node, ToString);
+ case Runtime::kInlineClassOf:
+ return Type::InternalizedStringOrNull();
case Runtime::kHasInPrototypeChain:
return Type::Boolean();
default:
@@ -1486,7 +1643,7 @@ Type* Typer::Visitor::TypeJSConvertReceiver(Node* node) {
Type* Typer::Visitor::TypeJSForInNext(Node* node) {
- return Type::Union(Type::Name(), Type::Undefined(), zone());
+ return Type::Union(Type::String(), Type::Undefined(), zone());
}
@@ -1530,6 +1687,8 @@ Type* Typer::Visitor::TypeJSGeneratorRestoreRegister(Node* node) {
Type* Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); }
+Type* Typer::Visitor::TypeJSDebugger(Node* node) { return Type::Any(); }
+
// Simplified operators.
Type* Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); }
@@ -1595,6 +1754,8 @@ Type* Typer::Visitor::StringFromCodePointTyper(Type* type, Typer* t) {
return Type::String();
}
+Type* Typer::Visitor::TypeStringCharAt(Node* node) { return Type::String(); }
+
Type* Typer::Visitor::TypeStringCharCodeAt(Node* node) {
return typer_->cache_.kUint16;
}
@@ -1607,6 +1768,10 @@ Type* Typer::Visitor::TypeStringFromCodePoint(Node* node) {
return TypeUnaryOp(node, StringFromCodePointTyper);
}
+Type* Typer::Visitor::TypeStringIndexOf(Node* node) {
+ return Type::Range(-1.0, String::kMaxLength - 1.0, zone());
+}
+
Type* Typer::Visitor::TypeCheckBounds(Node* node) {
Type* index = Operand(node, 0);
Type* length = Operand(node, 1);
@@ -1628,6 +1793,11 @@ Type* Typer::Visitor::TypeCheckIf(Node* node) {
return nullptr;
}
+Type* Typer::Visitor::TypeCheckInternalizedString(Node* node) {
+ Type* arg = Operand(node, 0);
+ return Type::Intersect(arg, Type::InternalizedString(), zone());
+}
+
Type* Typer::Visitor::TypeCheckMaps(Node* node) {
UNREACHABLE();
return nullptr;
@@ -1638,6 +1808,11 @@ Type* Typer::Visitor::TypeCheckNumber(Node* node) {
return Type::Intersect(arg, Type::Number(), zone());
}
+Type* Typer::Visitor::TypeCheckReceiver(Node* node) {
+ Type* arg = Operand(node, 0);
+ return Type::Intersect(arg, Type::Receiver(), zone());
+}
+
Type* Typer::Visitor::TypeCheckSmi(Node* node) {
Type* arg = Operand(node, 0);
return Type::Intersect(arg, Type::SignedSmall(), zone());
@@ -1726,8 +1901,12 @@ Type* Typer::Visitor::TypeStoreTypedElement(Node* node) {
return nullptr;
}
-Type* Typer::Visitor::TypeObjectIsCallable(Node* node) {
- return TypeUnaryOp(node, ObjectIsCallable);
+Type* Typer::Visitor::TypeObjectIsDetectableCallable(Node* node) {
+ return TypeUnaryOp(node, ObjectIsDetectableCallable);
+}
+
+Type* Typer::Visitor::TypeObjectIsNonCallable(Node* node) {
+ return TypeUnaryOp(node, ObjectIsNonCallable);
}
Type* Typer::Visitor::TypeObjectIsNumber(Node* node) {
@@ -1752,6 +1931,14 @@ Type* Typer::Visitor::TypeObjectIsUndetectable(Node* node) {
return TypeUnaryOp(node, ObjectIsUndetectable);
}
+Type* Typer::Visitor::TypeNewUnmappedArgumentsElements(Node* node) {
+ return Type::OtherInternal();
+}
+
+Type* Typer::Visitor::TypeNewRestParameterElements(Node* node) {
+ return Type::OtherInternal();
+}
+
Type* Typer::Visitor::TypeArrayBufferWasNeutered(Node* node) {
return Type::Boolean();
}