return GetElementAttributeWithInterceptor(receiver, index, continue_search);
}
- // Handle [] on String objects.
- if (this->IsStringObjectWithCharacterAt(index)) {
- return static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
- }
-
return GetElementAttributeWithoutInterceptor(
receiver, index, continue_search);
}
PropertyAttributes JSObject::GetElementAttributeWithoutInterceptor(
JSReceiver* receiver, uint32_t index, bool continue_search) {
- Isolate* isolate = GetIsolate();
- HandleScope scope(isolate);
- Handle<JSReceiver> hreceiver(receiver);
- Handle<JSObject> holder(this);
- PropertyAttributes attr = holder->GetElementsAccessor()->GetAttributes(
- *hreceiver, *holder, index);
+ PropertyAttributes attr = GetElementsAccessor()->GetAttributes(
+ receiver, this, index);
if (attr != ABSENT) return attr;
- if (holder->IsStringObjectWithCharacterAt(index)) {
+ // Handle [] on String objects.
+ if (IsStringObjectWithCharacterAt(index)) {
return static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
}
if (!continue_search) return ABSENT;
- Object* pt = holder->GetPrototype();
+ Object* pt = GetPrototype();
if (pt->IsJSProxy()) {
// We need to follow the spec and simulate a call to [[GetOwnProperty]].
- return JSProxy::cast(pt)->GetElementAttributeWithHandler(*hreceiver, index);
+ return JSProxy::cast(pt)->GetElementAttributeWithHandler(receiver, index);
}
if (pt->IsNull()) return ABSENT;
return JSObject::cast(pt)->GetElementAttributeWithReceiver(
- *hreceiver, index, true);
+ receiver, index, true);
}
}
+TEST(IndexedInterceptorWithStringProto) {
+ v8::HandleScope scope;
+ Handle<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->SetIndexedPropertyHandler(NULL,
+ NULL,
+ HasOwnPropertyIndexedPropertyQuery);
+ LocalContext context;
+ context->Global()->Set(v8_str("obj"), templ->NewInstance());
+ CompileRun("var s = new String('foobar'); obj.__proto__ = s;");
+ // These should be intercepted.
+ CHECK(CompileRun("42 in obj")->BooleanValue());
+ CHECK(CompileRun("'42' in obj")->BooleanValue());
+ // These should fall through to the String prototype.
+ CHECK(CompileRun("0 in obj")->BooleanValue());
+ CHECK(CompileRun("'0' in obj")->BooleanValue());
+ // And these should both fail.
+ CHECK(!CompileRun("32 in obj")->BooleanValue());
+ CHECK(!CompileRun("'32' in obj")->BooleanValue());
+}
+
+
void CheckCodeGenerationAllowed() {
Handle<Value> result = CompileRun("eval('42')");
CHECK_EQ(42, result->Int32Value());