Diff
Copied: branches/chromium/1132/LayoutTests/fast/canvas/webgl/array-override-set-expected.txt (from rev 118955, trunk/LayoutTests/fast/canvas/webgl/array-override-set-expected.txt) (0 => 119658)
--- branches/chromium/1132/LayoutTests/fast/canvas/webgl/array-override-set-expected.txt (rev 0)
+++ branches/chromium/1132/LayoutTests/fast/canvas/webgl/array-override-set-expected.txt 2012-06-07 01:26:48 UTC (rev 119658)
@@ -0,0 +1,27 @@
+Test overriding the set method of WebGL array
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+Regression test for ????
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS array[0] is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Copied: branches/chromium/1132/LayoutTests/fast/canvas/webgl/array-override-set.html (from rev 118955, trunk/LayoutTests/fast/canvas/webgl/array-override-set.html) (0 => 119658)
--- branches/chromium/1132/LayoutTests/fast/canvas/webgl/array-override-set.html (rev 0)
+++ branches/chromium/1132/LayoutTests/fast/canvas/webgl/array-override-set.html 2012-06-07 01:26:48 UTC (rev 119658)
@@ -0,0 +1,47 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+description("Test overriding the set method of WebGL array");
+
+debug('Regression test for ????');
+
+var array;
+var typeNames = ['Float32Array', 'Float64Array', 'Int8Array', 'Int16Array', 'Int32Array',
+ 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array']
+
+function overrideSetWithNumberAndConstruct(typeName) {
+ var type = window[typeName];
+ type.prototype.set = 0x3ffff;
+ array = new type([0], function() {});
+ shouldBe("array[0]", "0");
+}
+
+for (var i = 0; i < typeNames.length; i++) {
+ overrideSetWithNumberAndConstruct(typeNames[i]);
+}
+
+function overrideSetWithNumberAndSet(typeName) {
+ var type = window[typeName];
+ array = new type(10);
+ type.prototype.set = 0x3ffff;
+ array[0] = 8;
+ array.set([0], function() {});
+ shouldBe("array[0]", "0");
+}
+
+for (var i = 0; i < typeNames.length; i++) {
+ overrideSetWithNumberAndConstruct(typeNames[i]);
+}
+
+</script>
+
+<script src=""
+</body>
+</html>
Modified: branches/chromium/1132/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.cpp (119657 => 119658)
--- branches/chromium/1132/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.cpp 2012-06-07 01:00:17 UTC (rev 119657)
+++ branches/chromium/1132/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.cpp 2012-06-07 01:26:48 UTC (rev 119658)
@@ -27,51 +27,51 @@
#include "V8ArrayBufferViewCustom.h"
#include "V8ArrayBufferViewCustomScript.h"
+
#include <v8.h>
namespace WebCore {
// The random suffix helps to avoid name collision.
-const char fastSetFlagName[] = "TypedArray::FastSet::8NkZVq";
+const char hiddenCopyMethodName[] = "TypedArray::HiddenCopy::8NkZVq";
-bool fastSetInstalled(v8::Handle<v8::Object> array)
+v8::Handle<v8::Value> getHiddenCopyMethod(v8::Handle<v8::Object> prototype)
{
- // Use a hidden flag in the global object an indicator of whether the fast
- // 'set' is installed or not.
- v8::Handle<v8::Object> global = array->CreationContext()->Global();
- v8::Handle<v8::String> key = v8::String::New(fastSetFlagName);
- v8::Handle<v8::Value> fastSetFlag = global->GetHiddenValue(key);
- return !fastSetFlag.IsEmpty();
+ v8::Handle<v8::String> key = v8::String::New(hiddenCopyMethodName);
+ return prototype->GetHiddenValue(key);
}
-void installFastSet(v8::Handle<v8::Object> array)
-{
+v8::Handle<v8::Value> installHiddenCopyMethod(v8::Handle<v8::Object> prototype) {
v8::TryCatch tryCatch;
tryCatch.SetVerbose(true);
- v8::Handle<v8::Object> global = array->CreationContext()->Global();
- v8::Handle<v8::String> key = v8::String::New(fastSetFlagName);
- global->SetHiddenValue(key, v8::Boolean::New(true));
-
String source(reinterpret_cast<const char*>(V8ArrayBufferViewCustomScript_js),
sizeof(V8ArrayBufferViewCustomScript_js));
v8::Handle<v8::Script> script = v8::Script::Compile(v8String(source));
- script->Run();
+ v8::Handle<v8::Value> value = script->Run();
+ v8::Handle<v8::String> key = v8::String::New(hiddenCopyMethodName);
+ prototype->SetHiddenValue(key, value);
+ return value;
}
-
-void copyElements(v8::Handle<v8::Object> destArray, v8::Handle<v8::Object> srcArray, uint32_t offset)
+bool copyElements(v8::Handle<v8::Object> destArray, v8::Handle<v8::Object> srcArray, uint32_t length, uint32_t offset)
{
- v8::Handle<v8::String> key = v8::String::New("set");
- v8::Handle<v8::Function> set = destArray->Get(key).As<v8::Function>();
- v8::Handle<v8::Value> arguments[2];
- int numberOfArguments = 1;
+ v8::Handle<v8::Value> prototype_value = destArray->GetPrototype();
+ if (prototype_value.IsEmpty() || !prototype_value->IsObject())
+ return false;
+ v8::Handle<v8::Object> prototype = prototype_value.As<v8::Object>();
+ v8::Handle<v8::Value> value = getHiddenCopyMethod(prototype);
+ if (value.IsEmpty())
+ value = installHiddenCopyMethod(prototype);
+ if (value.IsEmpty() || !value->IsFunction())
+ return false;
+ v8::Handle<v8::Function> copy_method = value.As<v8::Function>();
+ v8::Handle<v8::Value> arguments[3];
arguments[0] = srcArray;
- if (offset) {
- arguments[1] = v8::Uint32::New(offset);
- numberOfArguments = 2;
- }
- set->Call(destArray, numberOfArguments, arguments);
+ arguments[1] = v8::Uint32::New(length);
+ arguments[2] = v8::Uint32::New(offset);
+ copy_method->Call(destArray, 3, arguments);
+ return true;
}
}
Modified: branches/chromium/1132/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h (119657 => 119658)
--- branches/chromium/1132/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h 2012-06-07 01:00:17 UTC (rev 119657)
+++ branches/chromium/1132/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h 2012-06-07 01:26:48 UTC (rev 119658)
@@ -40,20 +40,11 @@
namespace WebCore {
+// Copy the elements from the source array to the typed destination array.
+// Returns true if it succeeded, otherwise returns false.
+bool copyElements(v8::Handle<v8::Object> destArray, v8::Handle<v8::Object> srcArray, uint32_t length, uint32_t offset);
-// Check if the _javascript_ 'set' method was already installed
-// on the prototype of the given typed array.
-bool fastSetInstalled(v8::Handle<v8::Object> array);
-// Install the _javascript_ 'set' method on the prototype of
-// the given typed array.
-void installFastSet(v8::Handle<v8::Object> array);
-
-// Copy the elements from the source array to the typed destination array by
-// invoking the 'set' method of the destination array in JS.
-void copyElements(v8::Handle<v8::Object> destArray, v8::Handle<v8::Object> srcArray, uint32_t offset);
-
-
// Template function used by the ArrayBufferView*Constructor callbacks.
template<class ArrayClass, class ElementType>
v8::Handle<v8::Value> constructWebGLArrayWithArrayBufferArgument(const v8::Arguments& args, WrapperTypeInfo* type, v8::ExternalArrayType arrayType, bool hasIndexer)
@@ -176,8 +167,13 @@
V8DOMWrapper::setDOMWrapper(args.Holder(), type, array.get());
args.Holder()->SetIndexedPropertiesToExternalArrayData(array.get()->baseAddress(), arrayType, array.get()->length());
- if (!srcArray.IsEmpty())
- copyElements(args.Holder(), srcArray, 0);
+ if (!srcArray.IsEmpty()) {
+ bool copied = copyElements(args.Holder(), srcArray, len, 0);
+ if (!copied) {
+ for (unsigned i = 0; i < len; i++)
+ array->set(i, srcArray->Get(i)->NumberValue());
+ }
+ }
v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::New(args.Holder());
wrapper.MarkIndependent();
@@ -219,10 +215,8 @@
// Out of range offset or overflow
V8Proxy::setDOMException(INDEX_SIZE_ERR, args.GetIsolate());
else {
- if (!fastSetInstalled(args.Holder())) {
- installFastSet(args.Holder());
- copyElements(args.Holder(), array, offset);
- } else {
+ bool copied = copyElements(args.Holder(), array, length, offset);
+ if (!copied) {
for (uint32_t i = 0; i < length; i++)
impl->set(offset + i, array->Get(i)->NumberValue());
}
Modified: branches/chromium/1132/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustomScript.js (119657 => 119658)
--- branches/chromium/1132/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustomScript.js 2012-06-07 01:00:17 UTC (rev 119657)
+++ branches/chromium/1132/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustomScript.js 2012-06-07 01:26:48 UTC (rev 119658)
@@ -23,42 +23,14 @@
*/
(function() {
-
-var optimizeSetMethod = function(type)
-{
- if (typeof type === 'function' &&
- typeof type.prototype !== 'undefined' &&
- typeof type.prototype.set === 'function') {
- type.prototype.set = (function() {
- var nativeSet = type.prototype.set;
- var f = function(source, offset)
- {
- if (source.constructor === Array) {
- var length = source.length;
- offset = offset || 0;
- if (offset < 0 || offset + length > this.length) {
- return nativeSet.call(this, source, offset);
- }
- for (var i = 0; i < length; i++)
- this[i + offset] = source[i];
- } else
- return nativeSet.call(this, source, offset);
- }
- f.name = "set";
- return f;
- })();
+ return function(source, length, offset) {
+ if (offset == 0) {
+ for (var i = 0; i < length; i++)
+ this[i] = source[i];
+ } else {
+ for (var i = 0; i < length; i++)
+ this[i + offset] = source[i];
+ }
}
-};
-
-optimizeSetMethod(Float32Array);
-optimizeSetMethod(Float64Array);
-optimizeSetMethod(Int8Array);
-optimizeSetMethod(Int16Array);
-optimizeSetMethod(Int32Array);
-optimizeSetMethod(Uint8Array);
-optimizeSetMethod(Uint8ClampedArray);
-optimizeSetMethod(Uint16Array);
-optimizeSetMethod(Uint32Array);
-
})();