diff options
Diffstat (limited to 'js/src/jsapi-tests/testArrayBufferView.cpp')
-rw-r--r-- | js/src/jsapi-tests/testArrayBufferView.cpp | 179 |
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) |