Revision: 6869
Author: a...@chromium.org
Date: Mon Feb 21 07:59:23 2011
Log: 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
http://code.google.com/p/v8/source/detail?r=6869
Modified:
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/test/cctest/test-api.cc
=======================================
--- /branches/bleeding_edge/src/objects.cc Fri Feb 18 02:39:02 2011
+++ /branches/bleeding_edge/src/objects.cc Mon Feb 21 07:59:23 2011
@@ -6666,7 +6666,6 @@
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 @@
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 @@
}
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 @@
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 @@
}
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 @@
}
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();
}
=======================================
--- /branches/bleeding_edge/src/objects.h Wed Feb 16 04:10:48 2011
+++ /branches/bleeding_edge/src/objects.h Mon Feb 21 07:59:23 2011
@@ -1549,6 +1549,11 @@
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);
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Fri Feb 18 02:39:02 2011
+++ /branches/bleeding_edge/test/cctest/test-api.cc Mon Feb 21 07:59:23 2011
@@ -10881,6 +10881,53 @@
free(pixel_data);
}
}
+
+
+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) {
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev