Fix broken code passing typed data from Dart to V8. Attempted to match patterns in SerializeScriptValue.cpp

Fix JS interop to properly set set a hidden value when passing a Dart function to JS so that JS interop behavior is more consistent on dart2js and dartium.

BUG=

patch from issue 1724593002 at patchset 20001 (http://crrev.com/1724593002#ps20001)
diff --git a/Source/bindings/core/dart/DartJsInterop.cpp b/Source/bindings/core/dart/DartJsInterop.cpp
index 7478ca2..afad3c2 100644
--- a/Source/bindings/core/dart/DartJsInterop.cpp
+++ b/Source/bindings/core/dart/DartJsInterop.cpp
@@ -337,6 +337,7 @@
 
 v8::Local<v8::Value> JsInterop::fromDart(DartDOMData* domData, Dart_Handle handle, Dart_Handle& exception)
 {
+    v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
     v8::Handle<v8::Value> value = V8Converter::toV8IfPrimitive(domData, handle, exception);
     if (!value.IsEmpty() || exception)
         return value;
@@ -359,7 +360,13 @@
         DartHandleProxy::writePointerToProxy(functionProxy, handle);
         // The raw functionProxy doesn't behave enough like a true JS function
         // so we wrap it in a true JS function.
-        return domData->jsInteropData()->wrapDartFunction()->Call(functionProxy, 0, 0);
+        v8::Local<v8::Function> object = domData->jsInteropData()->wrapDartFunction()->Call(functionProxy, 0, 0).As<v8::Function>();
+
+        v8::Local<v8::String> existingDartWrapperKey = domData->jsInteropData()->existingDartWrapperHiddenField(v8Isolate);
+        v8::Local<v8::Object> containerForDartHandle = dartObjectTemplate()->InstanceTemplate()->NewInstance();
+        DartHandleProxy::writePointerToProxy(containerForDartHandle, handle);
+        object->SetHiddenValue(existingDartWrapperKey, containerForDartHandle);
+        return object;
     }
 
     v8::Local<v8::Object> proxy;
@@ -377,7 +384,6 @@
         proxy = dartObjectTemplate()->InstanceTemplate()->NewInstance();
     }
     DartHandleProxy::writePointerToProxy(proxy, handle);
-    v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
     proxy->SetHiddenValue(v8::String::NewFromUtf8(v8Isolate, "dartProxy"), v8::Boolean::New(v8Isolate, true));
 
     return proxy;
@@ -466,9 +472,6 @@
     DartDOMData* domData = DartDOMData::current();
     DartJsInteropData* interopData = domData->jsInteropData();
     v8::Local<v8::String> existingDartWrapperKey = interopData->existingDartWrapperHiddenField(v8Isolate);
-
-    // TODO(alanknight): This will fail for multiple isolates referencing the same JS object.
-    // We probably need to use a different property name for different isolates.
     v8::Local<v8::Value> hiddenValue = object->GetHiddenValue(existingDartWrapperKey);
 
     if (*hiddenValue && hiddenValue->IsObject()) {
diff --git a/Source/bindings/core/dart/V8Converter.cpp b/Source/bindings/core/dart/V8Converter.cpp
index 2200818..d51ac57 100644
--- a/Source/bindings/core/dart/V8Converter.cpp
+++ b/Source/bindings/core/dart/V8Converter.cpp
@@ -513,7 +513,10 @@
 v8::Handle<v8::Value> V8Converter::arrayBufferToV8(Dart_Handle value, Dart_Handle& exception)
 {
     ScriptState* state = DartUtilities::v8ScriptStateForCurrentIsolate();
-    return blink::toV8(DartUtilities::dartToExternalizedArrayBuffer(value, exception).get(), state->context()->Global(), state->isolate());
+    RefPtr<DOMArrayBuffer> arrayBuffer = DOMArrayBuffer::create(DartUtilities::dartToExternalizedArrayBuffer(value, exception));
+    v8::Handle<v8::Object> global = state->context()->Global();
+    v8::Isolate* v8Isolate = state->isolate();
+    return blink::toV8(arrayBuffer.get(), global, v8Isolate);
 }
 
 Dart_Handle V8Converter::arrayBufferToDart(v8::Handle<v8::Object> object, Dart_Handle& exception)
@@ -525,31 +528,71 @@
 {
     RefPtr<ArrayBufferView> view = DartUtilities::dartToExternalizedArrayBufferView(value, exception);
     ScriptState* state = DartUtilities::v8ScriptStateForCurrentIsolate();
+    unsigned byteOffset = view->byteOffset();
+    // this is copied from ScriptValueSerializer.
+    int elementByteSize = 1;
+    ArrayBuffer* data = view->buffer().get();
 
     switch (view->type()) {
     case ArrayBufferView::TypeInt8:
-        return blink::toV8(static_cast<Int8Array*>(view.get()), state->context()->Global(), state->isolate());
+        elementByteSize = sizeof(DOMInt8Array::ValueType);
+        break;
     case ArrayBufferView::TypeUint8:
-        return blink::toV8(static_cast<Uint8Array*>(view.get()), state->context()->Global(), state->isolate());
+        elementByteSize = sizeof(DOMUint8Array::ValueType);
+        break;
     case ArrayBufferView::TypeUint8Clamped:
-        return blink::toV8(static_cast<Uint8ClampedArray*>(view.get()), state->context()->Global(), state->isolate());
+        elementByteSize = sizeof(DOMUint8ClampedArray::ValueType);
+        break;
     case ArrayBufferView::TypeInt16:
-        return blink::toV8(static_cast<Int16Array*>(view.get()), state->context()->Global(), state->isolate());
+        elementByteSize = sizeof(DOMInt16Array::ValueType);
+        break;
     case ArrayBufferView::TypeUint16:
-        return blink::toV8(static_cast<Uint16Array*>(view.get()), state->context()->Global(), state->isolate());
+        elementByteSize = sizeof(DOMUint16Array::ValueType);
+        break;
     case ArrayBufferView::TypeInt32:
-        return blink::toV8(static_cast<Int32Array*>(view.get()), state->context()->Global(), state->isolate());
+        elementByteSize = sizeof(DOMInt32Array::ValueType);
+        break;
     case ArrayBufferView::TypeUint32:
-        return blink::toV8(static_cast<Uint32Array*>(view.get()), state->context()->Global(), state->isolate());
+        elementByteSize = sizeof(DOMUint32Array::ValueType);
+        break;
     case ArrayBufferView::TypeFloat32:
-        return blink::toV8(static_cast<Float32Array*>(view.get()), state->context()->Global(), state->isolate());
+        elementByteSize = sizeof(DOMFloat32Array::ValueType);
+        break;
     case ArrayBufferView::TypeFloat64:
-        return blink::toV8(static_cast<Float64Array*>(view.get()), state->context()->Global(), state->isolate());
+        elementByteSize = sizeof(DOMFloat64Array::ValueType);
+        break;
+    case ArrayBufferView::TypeDataView:
+        elementByteSize = sizeof(DOMDataView::ValueType);
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+    unsigned numElements = view->byteLength() / elementByteSize;
+
+    switch (view->type()) {
+    case ArrayBufferView::TypeInt8:
+        return blink::toV8(DOMInt8Array::create(data, byteOffset, numElements), state->context()->Global(), state->isolate());
+    case ArrayBufferView::TypeUint8:
+        return blink::toV8(DOMUint8Array::create(data, byteOffset, numElements), state->context()->Global(), state->isolate());
+    case ArrayBufferView::TypeUint8Clamped:
+        return blink::toV8(DOMUint8ClampedArray::create(data, byteOffset, numElements), state->context()->Global(), state->isolate());
+    case ArrayBufferView::TypeInt16:
+        return blink::toV8(DOMInt16Array::create(data, byteOffset, numElements), state->context()->Global(), state->isolate());
+    case ArrayBufferView::TypeUint16:
+        return blink::toV8(DOMUint16Array::create(data, byteOffset, numElements), state->context()->Global(), state->isolate());
+    case ArrayBufferView::TypeInt32:
+        return blink::toV8(DOMInt32Array::create(data, byteOffset, numElements), state->context()->Global(), state->isolate());
+    case ArrayBufferView::TypeUint32:
+        return blink::toV8(DOMUint32Array::create(data, byteOffset, numElements), state->context()->Global(), state->isolate());
+    case ArrayBufferView::TypeFloat32:
+        return blink::toV8(DOMFloat32Array::create(data, byteOffset, numElements), state->context()->Global(), state->isolate());
+    case ArrayBufferView::TypeFloat64:
+        return blink::toV8(DOMFloat64Array::create(data, byteOffset, numElements), state->context()->Global(), state->isolate());
     case ArrayBufferView::TypeDataView:
         {
+            RefPtr<DOMArrayBufferView> domArrayBuffView = adoptRef(new DOMArrayBufferView(view.get()));
             // TODO(terry): Had to move protected constructor to public in
             //              core/dom/DOMArrayBufferView.h
-            RefPtr<DOMArrayBufferView> domArrayBuffView = new DOMArrayBufferView(view.get());
             return blink::toV8(DOMDataView::create(domArrayBuffView->bufferBase(),
                 domArrayBuffView->byteOffset(),
                 domArrayBuffView->byteLength()),