}
+Smi* JSObject::InterceptorPropertyLookupHint(String* name) {
+ // TODO(antonm): Do we want to do any shortcuts for global object?
+ if (HasFastProperties()) {
+ LookupResult lookup;
+ LocalLookupRealNamedProperty(name, &lookup);
+ if (lookup.IsValid()) {
+ if (lookup.type() == FIELD && lookup.IsCacheable()) {
+ return Smi::FromInt(lookup.GetFieldIndex());
+ }
+ } else {
+ return Smi::FromInt(kLookupInPrototype);
+ }
+ }
+
+ return Smi::FromInt(kLookupInHolder);
+}
+
+
bool AccessorInfo::all_can_read() {
return BooleanBit::get(flag(), kAllCanReadBit);
}
}
-Object* JSObject::GetPropertyWithInterceptor(JSObject* receiver,
- String* name,
- PropertyAttributes* attributes) {
+Object* JSObject::GetPropertyWithInterceptorProper(
+ JSObject* receiver,
+ String* name,
+ PropertyAttributes* attributes) {
HandleScope scope;
Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
Handle<JSObject> receiver_handle(receiver);
}
}
- Object* raw_result = holder_handle->GetPropertyPostInterceptor(
+ return NULL;
+}
+
+
+Object* JSObject::GetInterceptorPropertyWithLookupHint(
+ JSObject* receiver,
+ Smi* lookup_hint,
+ String* name,
+ PropertyAttributes* attributes) {
+ HandleScope scope;
+ Handle<JSObject> receiver_handle(receiver);
+ Handle<JSObject> holder_handle(this);
+ Handle<String> name_handle(name);
+
+ Object* result = GetPropertyWithInterceptorProper(receiver, name, attributes);
+ if (result) return result;
+
+ int property_index = lookup_hint->value();
+ if (property_index >= 0) {
+ result = holder_handle->FastPropertyAt(property_index);
+ } else {
+ switch (property_index) {
+ case kLookupInPrototype: {
+ Object* pt = holder_handle->GetPrototype();
+ *attributes = ABSENT;
+ if (pt == Heap::null_value()) return Heap::undefined_value();
+ result = pt->GetPropertyWithReceiver(
+ *receiver_handle,
+ *name_handle,
+ attributes);
+ RETURN_IF_SCHEDULED_EXCEPTION();
+ }
+ break;
+
+ case kLookupInHolder:
+ result = holder_handle->GetPropertyPostInterceptor(
+ *receiver_handle,
+ *name_handle,
+ attributes);
+ RETURN_IF_SCHEDULED_EXCEPTION();
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ return result;
+}
+
+
+Object* JSObject::GetPropertyWithInterceptor(
+ JSObject* receiver,
+ String* name,
+ PropertyAttributes* attributes) {
+ HandleScope scope;
+ Handle<JSObject> receiver_handle(receiver);
+ Handle<JSObject> holder_handle(this);
+ Handle<String> name_handle(name);
+
+ Object* result = GetPropertyWithInterceptorProper(receiver, name, attributes);
+ if (result) return result;
+
+ result = holder_handle->GetPropertyPostInterceptor(
*receiver_handle,
*name_handle,
attributes);
RETURN_IF_SCHEDULED_EXCEPTION();
- return raw_result;
+ return result;
}
JSObject* recv = JSObject::cast(args[0]);
JSObject* holder = JSObject::cast(args[1]);
String* name = String::cast(args[2]);
+ Smi* lookup_hint = Smi::cast(args[3]);
ASSERT(holder->HasNamedInterceptor());
PropertyAttributes attr = NONE;
- Object* result = holder->GetPropertyWithInterceptor(recv, name, &attr);
+ Object* result = holder->GetInterceptorPropertyWithLookupHint(
+ recv, lookup_hint, name, &attr);
if (result->IsFailure()) return result;
// If the property is present, return it.