Commit c2969bfb authored by ager@chromium.org's avatar ager@chromium.org

Implement pixel array elements access in the presence of an

interceptor that does not handle the elements load.

Review URL: http://codereview.chromium.org/6551001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6869 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f13f84ae
......@@ -6666,7 +6666,6 @@ bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) {
break;
}
case PIXEL_ELEMENTS: {
// TODO(iposva): Add testcase.
PixelArray* pixels = PixelArray::cast(elements());
if (index < static_cast<uint32_t>(pixels->length())) {
return true;
......@@ -6680,7 +6679,6 @@ bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) {
case EXTERNAL_INT_ELEMENTS:
case EXTERNAL_UNSIGNED_INT_ELEMENTS:
case EXTERNAL_FLOAT_ELEMENTS: {
// TODO(kbr): Add testcase.
ExternalArray* array = ExternalArray::cast(elements());
if (index < static_cast<uint32_t>(array->length())) {
return true;
......@@ -7271,11 +7269,7 @@ MaybeObject* JSObject::GetElementPostInterceptor(Object* receiver,
}
break;
}
case PIXEL_ELEMENTS: {
// TODO(iposva): Add testcase and implement.
UNIMPLEMENTED();
break;
}
case PIXEL_ELEMENTS:
case EXTERNAL_BYTE_ELEMENTS:
case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
case EXTERNAL_SHORT_ELEMENTS:
......@@ -7283,8 +7277,8 @@ MaybeObject* JSObject::GetElementPostInterceptor(Object* receiver,
case EXTERNAL_INT_ELEMENTS:
case EXTERNAL_UNSIGNED_INT_ELEMENTS:
case EXTERNAL_FLOAT_ELEMENTS: {
// TODO(kbr): Add testcase and implement.
UNIMPLEMENTED();
MaybeObject* value = GetExternalElement(index);
if (!value->ToObjectUnchecked()->IsUndefined()) return value;
break;
}
case DICTIONARY_ELEMENTS: {
......@@ -7372,6 +7366,46 @@ MaybeObject* JSObject::GetElementWithReceiver(Object* receiver,
}
break;
}
case PIXEL_ELEMENTS:
case EXTERNAL_BYTE_ELEMENTS:
case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
case EXTERNAL_SHORT_ELEMENTS:
case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
case EXTERNAL_INT_ELEMENTS:
case EXTERNAL_UNSIGNED_INT_ELEMENTS:
case EXTERNAL_FLOAT_ELEMENTS: {
MaybeObject* value = GetExternalElement(index);
if (!value->ToObjectUnchecked()->IsUndefined()) return value;
break;
}
case DICTIONARY_ELEMENTS: {
NumberDictionary* dictionary = element_dictionary();
int entry = dictionary->FindEntry(index);
if (entry != NumberDictionary::kNotFound) {
Object* element = dictionary->ValueAt(entry);
PropertyDetails details = dictionary->DetailsAt(entry);
if (details.type() == CALLBACKS) {
return GetElementWithCallback(receiver,
element,
index,
this);
}
return element;
}
break;
}
}
Object* pt = GetPrototype();
if (pt == Heap::null_value()) return Heap::undefined_value();
return pt->GetElementWithReceiver(receiver, index);
}
MaybeObject* JSObject::GetExternalElement(uint32_t index) {
// Get element works for both JSObject and JSArray since
// JSArray::length cannot change.
switch (GetElementsKind()) {
case PIXEL_ELEMENTS: {
PixelArray* pixels = PixelArray::cast(elements());
if (index < static_cast<uint32_t>(pixels->length())) {
......@@ -7439,27 +7473,12 @@ MaybeObject* JSObject::GetElementWithReceiver(Object* receiver,
}
break;
}
case DICTIONARY_ELEMENTS: {
NumberDictionary* dictionary = element_dictionary();
int entry = dictionary->FindEntry(index);
if (entry != NumberDictionary::kNotFound) {
Object* element = dictionary->ValueAt(entry);
PropertyDetails details = dictionary->DetailsAt(entry);
if (details.type() == CALLBACKS) {
return GetElementWithCallback(receiver,
element,
index,
this);
}
return element;
}
case FAST_ELEMENTS:
case DICTIONARY_ELEMENTS:
UNREACHABLE();
break;
}
}
Object* pt = GetPrototype();
if (pt == Heap::null_value()) return Heap::undefined_value();
return pt->GetElementWithReceiver(receiver, index);
return Heap::undefined_value();
}
......
......@@ -1549,6 +1549,11 @@ class JSObject: public HeapObject {
MaybeObject* GetElementWithReceiver(Object* receiver, uint32_t index);
MaybeObject* GetElementWithInterceptor(Object* receiver, uint32_t index);
// Get external element value at index if there is one and undefined
// otherwise. Can return a failure if allocation of a heap number
// failed.
MaybeObject* GetExternalElement(uint32_t index);
MUST_USE_RESULT MaybeObject* SetFastElementsCapacityAndLength(int capacity,
int length);
MUST_USE_RESULT MaybeObject* SetSlowElements(Object* length);
......
......@@ -10883,6 +10883,53 @@ THREADED_TEST(PixelArrayInfo) {
}
static v8::Handle<Value> NotHandledIndexedPropertyGetter(
uint32_t index,
const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
return v8::Handle<Value>();
}
static v8::Handle<Value> NotHandledIndexedPropertySetter(
uint32_t index,
Local<Value> value,
const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
return v8::Handle<Value>();
}
THREADED_TEST(PixelArrayWithInterceptor) {
v8::HandleScope scope;
LocalContext context;
const int kElementCount = 260;
uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount));
i::Handle<i::PixelArray> pixels =
i::Factory::NewPixelArray(kElementCount, pixel_data);
for (int i = 0; i < kElementCount; i++) {
pixels->set(i, i % 256);
}
v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New();
templ->SetIndexedPropertyHandler(NotHandledIndexedPropertyGetter,
NotHandledIndexedPropertySetter);
v8::Handle<v8::Object> obj = templ->NewInstance();
obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount);
context->Global()->Set(v8_str("pixels"), obj);
v8::Handle<v8::Value> result = CompileRun("pixels[1]");
CHECK_EQ(1, result->Int32Value());
result = CompileRun("var sum = 0;"
"for (var i = 0; i < 8; i++) {"
" sum += pixels[i] = pixels[i] = -i;"
"}"
"sum;");
CHECK_EQ(-28, result->Int32Value());
result = CompileRun("pixels.hasOwnProperty('1')");
CHECK(result->BooleanValue());
free(pixel_data);
}
static int ExternalArrayElementSize(v8::ExternalArrayType array_type) {
switch (array_type) {
case v8::kExternalByteArray:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment