Index: src/compiler/typer.cc |
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc |
index 19aaaa531474ac599f6f74267c0bc072cfef59c7..74904a3601569966197a9dd2a8477595b6b853c2 100644 |
--- a/src/compiler/typer.cc |
+++ b/src/compiler/typer.cc |
@@ -1262,7 +1262,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(); } |