summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/typer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/typer.cc')
-rw-r--r--deps/v8/src/compiler/typer.cc172
1 files changed, 154 insertions, 18 deletions
diff --git a/deps/v8/src/compiler/typer.cc b/deps/v8/src/compiler/typer.cc
index d6a4a58fa0..c1f816d34b 100644
--- a/deps/v8/src/compiler/typer.cc
+++ b/deps/v8/src/compiler/typer.cc
@@ -54,12 +54,15 @@ Typer::Typer(Isolate* isolate, Graph* graph, Flags flags,
singleton_false_ = Type::Constant(factory->false_value(), zone);
singleton_true_ = Type::Constant(factory->true_value(), zone);
+ singleton_the_hole_ = Type::Constant(factory->the_hole_value(), zone);
signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone);
unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone);
falsish_ = Type::Union(
Type::Undetectable(),
- Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone),
- Type::NullOrUndefined(), zone),
+ Type::Union(
+ Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone),
+ Type::NullOrUndefined(), zone),
+ singleton_the_hole_, zone),
zone);
truish_ = Type::Union(
singleton_true_,
@@ -252,7 +255,6 @@ class Typer::Visitor : public Reducer {
JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
#undef DECLARE_METHOD
- static Type* JSUnaryNotTyper(Type*, Typer*);
static Type* JSTypeOfTyper(Type*, Typer*);
static Type* JSLoadPropertyTyper(Type*, Type*, Typer*);
static Type* JSCallFunctionTyper(Type*, Typer*);
@@ -634,6 +636,11 @@ Type* Typer::Visitor::TypeStateValues(Node* node) {
}
+Type* Typer::Visitor::TypeObjectState(Node* node) {
+ return Type::Internal(zone());
+}
+
+
Type* Typer::Visitor::TypeTypedStateValues(Node* node) {
return Type::Internal(zone());
}
@@ -697,6 +704,10 @@ 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)) {
+ return t->singleton_false_;
+ }
if (lhs->IsConstant() && rhs->Is(lhs)) {
// Types are equal and are inhabited only by a single semantic value,
// which is not nan due to the earlier check.
@@ -1136,16 +1147,6 @@ Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
// JS unary operators.
-Type* Typer::Visitor::JSUnaryNotTyper(Type* type, Typer* t) {
- return Invert(ToBoolean(type, t), t);
-}
-
-
-Type* Typer::Visitor::TypeJSUnaryNot(Node* node) {
- return TypeUnaryOp(node, JSUnaryNotTyper);
-}
-
-
Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) {
Factory* const f = t->isolate()->factory();
if (type->Is(Type::Boolean())) {
@@ -1215,13 +1216,23 @@ Type* Typer::Visitor::TypeJSCreateArguments(Node* node) {
}
+Type* Typer::Visitor::TypeJSCreateArray(Node* node) {
+ return Type::OtherObject();
+}
+
+
Type* Typer::Visitor::TypeJSCreateClosure(Node* node) {
+ return Type::Function();
+}
+
+
+Type* Typer::Visitor::TypeJSCreateIterResultObject(Node* node) {
return Type::OtherObject();
}
Type* Typer::Visitor::TypeJSCreateLiteralArray(Node* node) {
- return Type::None(), Type::OtherObject();
+ return Type::OtherObject();
}
@@ -1230,6 +1241,11 @@ Type* Typer::Visitor::TypeJSCreateLiteralObject(Node* node) {
}
+Type* Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) {
+ return Type::OtherObject();
+}
+
+
Type* Typer::Visitor::JSLoadPropertyTyper(Type* object, Type* name, Typer* t) {
// TODO(rossberg): Use range types and sized array types to filter undefined.
if (object->IsArray() && name->Is(Type::Integral32())) {
@@ -1245,7 +1261,37 @@ Type* Typer::Visitor::TypeJSLoadProperty(Node* node) {
}
-Type* Typer::Visitor::TypeJSLoadNamed(Node* node) { return Type::Any(); }
+Type* Typer::Visitor::TypeJSLoadNamed(Node* node) {
+ Factory* const f = isolate()->factory();
+ Handle<Name> name = NamedAccessOf(node->op()).name();
+ if (name.is_identical_to(f->prototype_string())) {
+ Type* receiver = Operand(node, 0);
+ if (receiver->Is(Type::None())) return Type::None();
+ if (receiver->IsConstant() &&
+ receiver->AsConstant()->Value()->IsJSFunction()) {
+ Handle<JSFunction> function =
+ Handle<JSFunction>::cast(receiver->AsConstant()->Value());
+ if (function->has_prototype()) {
+ // We need to add a code dependency on the initial map of the {function}
+ // in order to be notified about changes to "prototype" of {function},
+ // so we can only infer a constant type if deoptimization is enabled.
+ if (flags() & kDeoptimizationEnabled) {
+ JSFunction::EnsureHasInitialMap(function);
+ Handle<Map> initial_map(function->initial_map(), isolate());
+ dependencies()->AssumeInitialMapCantChange(initial_map);
+ return Type::Constant(handle(initial_map->prototype(), isolate()),
+ zone());
+ }
+ }
+ } else if (receiver->IsClass() &&
+ receiver->AsClass()->Map()->IsJSFunctionMap()) {
+ Handle<Map> map = receiver->AsClass()->Map();
+ return map->has_non_instance_prototype() ? Type::Primitive(zone())
+ : Type::Receiver(zone());
+ }
+ }
+ return Type::Any();
+}
Type* Typer::Visitor::TypeJSLoadGlobal(Node* node) { return Type::Any(); }
@@ -1369,6 +1415,10 @@ Type* Typer::Visitor::TypeJSInstanceOf(Node* node) {
Type* Typer::Visitor::TypeJSLoadContext(Node* node) {
+ ContextAccess const& access = ContextAccessOf(node->op());
+ if (access.index() == Context::EXTENSION_INDEX) {
+ return Type::TaggedPointer();
+ }
// Since contexts are mutable, we just return the top.
return Type::Any();
}
@@ -1507,12 +1557,12 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
case Runtime::kInlineIsMinusZero:
case Runtime::kInlineIsFunction:
case Runtime::kInlineIsRegExp:
+ case Runtime::kInlineIsJSReceiver:
return Type::Boolean(zone());
case Runtime::kInlineDoubleLo:
case Runtime::kInlineDoubleHi:
return Type::Signed32();
case Runtime::kInlineConstructDouble:
- case Runtime::kInlineDateField:
case Runtime::kInlineMathFloor:
case Runtime::kInlineMathSqrt:
case Runtime::kInlineMathAcos:
@@ -1522,8 +1572,11 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
return Type::Number();
case Runtime::kInlineMathClz32:
return Type::Range(0, 32, zone());
- case Runtime::kInlineStringGetLength:
- return Type::Range(0, String::kMaxLength, zone());
+ case Runtime::kInlineCreateIterResultObject:
+ case Runtime::kInlineRegExpConstructResult:
+ return Type::OtherObject();
+ case Runtime::kInlineSubString:
+ return Type::String();
case Runtime::kInlineToInteger:
return TypeUnaryOp(node, ToInteger);
case Runtime::kInlineToLength:
@@ -1540,6 +1593,8 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
return TypeUnaryOp(node, ToPrimitive);
case Runtime::kInlineToString:
return TypeUnaryOp(node, ToString);
+ case Runtime::kHasInPrototypeChain:
+ return Type::Boolean();
default:
break;
}
@@ -1677,6 +1732,11 @@ Type* Typer::Visitor::TypeNumberToUint32(Node* node) {
}
+Type* Typer::Visitor::TypeNumberIsHoleNaN(Node* node) {
+ return Type::Boolean(zone());
+}
+
+
Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
return TypeUnaryOp(node, ToNumber);
}
@@ -2025,9 +2085,19 @@ Type* Typer::Visitor::TypeUint32MulHigh(Node* node) {
Type* Typer::Visitor::TypeInt64Add(Node* node) { return Type::Internal(); }
+Type* Typer::Visitor::TypeInt64AddWithOverflow(Node* node) {
+ return Type::Internal();
+}
+
+
Type* Typer::Visitor::TypeInt64Sub(Node* node) { return Type::Internal(); }
+Type* Typer::Visitor::TypeInt64SubWithOverflow(Node* node) {
+ return Type::Internal();
+}
+
+
Type* Typer::Visitor::TypeInt64Mul(Node* node) { return Type::Internal(); }
@@ -2075,6 +2145,26 @@ Type* Typer::Visitor::TypeChangeFloat64ToUint32(Node* node) {
}
+Type* Typer::Visitor::TypeTryTruncateFloat32ToInt64(Node* node) {
+ return Type::Internal();
+}
+
+
+Type* Typer::Visitor::TypeTryTruncateFloat64ToInt64(Node* node) {
+ return Type::Internal();
+}
+
+
+Type* Typer::Visitor::TypeTryTruncateFloat32ToUint64(Node* node) {
+ return Type::Internal();
+}
+
+
+Type* Typer::Visitor::TypeTryTruncateFloat64ToUint64(Node* node) {
+ return Type::Internal();
+}
+
+
Type* Typer::Visitor::TypeChangeInt32ToFloat64(Node* node) {
return Type::Intersect(Type::Signed32(), Type::UntaggedFloat64(), zone());
}
@@ -2120,6 +2210,16 @@ Type* Typer::Visitor::TypeRoundInt64ToFloat64(Node* node) {
}
+Type* Typer::Visitor::TypeRoundUint64ToFloat32(Node* node) {
+ return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat32(), zone());
+}
+
+
+Type* Typer::Visitor::TypeRoundUint64ToFloat64(Node* node) {
+ return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat64(), zone());
+}
+
+
Type* Typer::Visitor::TypeBitcastFloat32ToInt32(Node* node) {
return Type::Number();
}
@@ -2223,12 +2323,36 @@ Type* Typer::Visitor::TypeFloat64LessThanOrEqual(Node* node) {
}
+Type* Typer::Visitor::TypeFloat32RoundDown(Node* node) {
+ // TODO(sigurds): We could have a tighter bound here.
+ return Type::Number();
+}
+
+
Type* Typer::Visitor::TypeFloat64RoundDown(Node* node) {
// TODO(sigurds): We could have a tighter bound here.
return Type::Number();
}
+Type* Typer::Visitor::TypeFloat32RoundUp(Node* node) {
+ // TODO(sigurds): We could have a tighter bound here.
+ return Type::Number();
+}
+
+
+Type* Typer::Visitor::TypeFloat64RoundUp(Node* node) {
+ // TODO(sigurds): We could have a tighter bound here.
+ return Type::Number();
+}
+
+
+Type* Typer::Visitor::TypeFloat32RoundTruncate(Node* node) {
+ // TODO(sigurds): We could have a tighter bound here.
+ return Type::Number();
+}
+
+
Type* Typer::Visitor::TypeFloat64RoundTruncate(Node* node) {
// TODO(sigurds): We could have a tighter bound here.
return Type::Number();
@@ -2241,6 +2365,18 @@ Type* Typer::Visitor::TypeFloat64RoundTiesAway(Node* node) {
}
+Type* Typer::Visitor::TypeFloat32RoundTiesEven(Node* node) {
+ // TODO(sigurds): We could have a tighter bound here.
+ return Type::Number();
+}
+
+
+Type* Typer::Visitor::TypeFloat64RoundTiesEven(Node* node) {
+ // TODO(sigurds): We could have a tighter bound here.
+ return Type::Number();
+}
+
+
Type* Typer::Visitor::TypeFloat64ExtractLowWord32(Node* node) {
return Type::Signed32();
}