diff options
Diffstat (limited to 'src/compiler/typer.cc')
-rw-r--r-- | src/compiler/typer.cc | 229 |
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(); } |