summaryrefslogtreecommitdiffstats
path: root/js/src/jsapi-tests/testArrayBufferView.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jsapi-tests/testArrayBufferView.cpp')
-rw-r--r--js/src/jsapi-tests/testArrayBufferView.cpp179
1 files changed, 179 insertions, 0 deletions
diff --git a/js/src/jsapi-tests/testArrayBufferView.cpp b/js/src/jsapi-tests/testArrayBufferView.cpp
new file mode 100644
index 000000000..e0b4f3af6
--- /dev/null
+++ b/js/src/jsapi-tests/testArrayBufferView.cpp
@@ -0,0 +1,179 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ */
+
+#include "jscompartment.h"
+#include "jsfriendapi.h"
+
+#include "jsapi-tests/tests.h"
+
+#include "jscompartmentinlines.h"
+
+using namespace js;
+
+BEGIN_TEST(testArrayBufferView_type)
+{
+ CHECK((TestViewType<uint8_t,
+ Create<JS_NewUint8Array, 7>,
+ JS_GetObjectAsUint8Array,
+ js::Scalar::Uint8,
+ 7, 7>(cx)));
+
+ CHECK((TestViewType<int8_t,
+ Create<JS_NewInt8Array, 33>,
+ JS_GetObjectAsInt8Array,
+ js::Scalar::Int8,
+ 33, 33>(cx)));
+
+ CHECK((TestViewType<uint8_t,
+ Create<JS_NewUint8ClampedArray, 7>,
+ JS_GetObjectAsUint8ClampedArray,
+ js::Scalar::Uint8Clamped,
+ 7, 7>(cx)));
+
+ CHECK((TestViewType<uint16_t,
+ Create<JS_NewUint16Array, 3>,
+ JS_GetObjectAsUint16Array,
+ js::Scalar::Uint16,
+ 3, 6>(cx)));
+
+ CHECK((TestViewType<int16_t,
+ Create<JS_NewInt16Array, 17>,
+ JS_GetObjectAsInt16Array,
+ js::Scalar::Int16,
+ 17, 34>(cx)));
+
+ CHECK((TestViewType<uint32_t,
+ Create<JS_NewUint32Array, 15>,
+ JS_GetObjectAsUint32Array,
+ js::Scalar::Uint32,
+ 15, 60>(cx)));
+
+ CHECK((TestViewType<int32_t,
+ Create<JS_NewInt32Array, 8>,
+ JS_GetObjectAsInt32Array,
+ js::Scalar::Int32,
+ 8, 32>(cx)));
+
+ CHECK((TestViewType<float,
+ Create<JS_NewFloat32Array, 7>,
+ JS_GetObjectAsFloat32Array,
+ js::Scalar::Float32,
+ 7, 28>(cx)));
+
+ CHECK((TestViewType<double,
+ Create<JS_NewFloat64Array, 9>,
+ JS_GetObjectAsFloat64Array,
+ js::Scalar::Float64,
+ 9, 72>(cx)));
+
+ CHECK((TestViewType<uint8_t,
+ CreateDataView,
+ JS_GetObjectAsArrayBufferView,
+ js::Scalar::MaxTypedArrayViewType,
+ 8, 8>(cx)));
+
+ JS::Rooted<JS::Value> hasTypedObject(cx);
+ EVAL("typeof TypedObject !== 'undefined'", &hasTypedObject);
+ if (hasTypedObject.isTrue()) {
+ JS::Rooted<JS::Value> tval(cx);
+ EVAL("var T = new TypedObject.StructType({ x: TypedObject.uint32 });\n"
+ "new T(new ArrayBuffer(4));",
+ &tval);
+
+ JS::Rooted<JSObject*> tobj(cx, &tval.toObject());
+ CHECK(!JS_IsArrayBufferViewObject(tobj));
+ }
+
+ return true;
+}
+
+static JSObject*
+CreateDataView(JSContext* cx)
+{
+ JS::Rooted<JSObject*> buffer(cx, JS_NewArrayBuffer(cx, 8));
+ if (!buffer)
+ return nullptr;
+ return JS_NewDataView(cx, buffer, 0, 8);
+}
+
+template<JSObject * CreateTypedArray(JSContext* cx, uint32_t length),
+ size_t Length>
+static JSObject*
+Create(JSContext* cx)
+{
+ return CreateTypedArray(cx, Length);
+}
+
+template<typename T,
+ JSObject * CreateViewType(JSContext* cx),
+ JSObject * GetObjectAs(JSObject* obj, uint32_t* length, bool* isSharedMemory, T** data),
+ js::Scalar::Type ExpectedType,
+ uint32_t ExpectedLength,
+ uint32_t ExpectedByteLength>
+bool TestViewType(JSContext* cx)
+{
+ JS::Rooted<JSObject*> obj(cx, CreateViewType(cx));
+ CHECK(obj);
+
+ CHECK(JS_IsArrayBufferViewObject(obj));
+
+ CHECK(JS_GetArrayBufferViewType(obj) == ExpectedType);
+
+ CHECK(JS_GetArrayBufferViewByteLength(obj) == ExpectedByteLength);
+
+ {
+ JS::AutoCheckCannotGC nogc;
+ bool shared1;
+ T* data1 = static_cast<T*>(JS_GetArrayBufferViewData(obj, &shared1, nogc));
+
+ T* data2;
+ bool shared2;
+ uint32_t len;
+ CHECK(obj == GetObjectAs(obj, &len, &shared2, &data2));
+ CHECK(data1 == data2);
+ CHECK(shared1 == shared2);
+ CHECK(len == ExpectedLength);
+ }
+
+ JS::CompartmentOptions options;
+ JS::RootedObject otherGlobal(cx, JS_NewGlobalObject(cx, basicGlobalClass(), nullptr,
+ JS::DontFireOnNewGlobalHook, options));
+ CHECK(otherGlobal);
+
+ JS::Rooted<JSObject*> buffer(cx);
+ {
+ AutoCompartment ac(cx, otherGlobal);
+ buffer = JS_NewArrayBuffer(cx, 8);
+ CHECK(buffer);
+ CHECK(buffer->as<ArrayBufferObject>().byteLength() == 8);
+ }
+ CHECK(buffer->compartment() == otherGlobal->compartment());
+ CHECK(JS_WrapObject(cx, &buffer));
+ CHECK(buffer->compartment() == global->compartment());
+
+ JS::Rooted<JSObject*> dataview(cx, JS_NewDataView(cx, buffer, 4, 4));
+ CHECK(dataview);
+ CHECK(dataview->is<ProxyObject>());
+
+ JS::Rooted<JS::Value> val(cx);
+
+ val = ObjectValue(*dataview);
+ CHECK(JS_SetProperty(cx, global, "view", val));
+
+ EVAL("view.buffer", &val);
+ CHECK(val.toObject().is<ProxyObject>());
+
+ CHECK(dataview->compartment() == global->compartment());
+ JS::Rooted<JSObject*> otherView(cx, js::UncheckedUnwrap(dataview));
+ CHECK(otherView->compartment() == otherGlobal->compartment());
+ JS::Rooted<JSObject*> otherBuffer(cx, js::UncheckedUnwrap(&val.toObject()));
+ CHECK(otherBuffer->compartment() == otherGlobal->compartment());
+
+ EVAL("Object.getPrototypeOf(view) === DataView.prototype", &val);
+ CHECK(val.toBoolean() == true);
+
+ return true;
+}
+
+END_TEST(testArrayBufferView_type)