Bug 1852740: add tests for the `fetchpriority` attribute in Link headers. r=necko...
[gecko.git] / js / src / jsapi-tests / testArrayBufferView.cpp
blob82745f1d002932d75aeb25d2735cea06f529465e
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 */
5 /* This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
9 #include "jsfriendapi.h"
11 #include "js/ArrayBuffer.h" // JS::NewArrayBuffer
12 #include "js/experimental/TypedData.h" // JS_GetArrayBufferView{Type,ByteLength,Data}, JS_GetObjectAsArrayBufferView, JS_GetObjectAs{{Ui,I}nt{8,16,32},Float{32,64}}Array, JS_IsArrayBufferViewObject, JS_NewDataView, JS_New{{Ui,I}nt{8,16,32},Float{32,64},Uint8Clamped}Array
13 #include "js/GlobalObject.h" // JS_NewGlobalObject
14 #include "js/PropertyAndElement.h" // JS_SetProperty
15 #include "js/ScalarType.h" // js::Scalar::Type
16 #include "jsapi-tests/tests.h"
17 #include "vm/ProxyObject.h"
18 #include "vm/Realm.h"
19 #include "vm/Uint8Clamped.h" // js::uint8_clamped_t
21 #include "vm/JSObject-inl.h"
22 #include "vm/Realm-inl.h"
23 #include "vm/TypedArrayObject-inl.h" // TypeIDOfType
25 using namespace js;
27 template <class ViewType>
28 static JSObject* Create(JSContext* cx, size_t len) {
29 return ViewType::create(cx, len).asObject();
32 template <>
33 JSObject* Create<JS::DataView>(JSContext* cx, size_t len) {
34 JS::Rooted<JSObject*> buffer(cx, JS::NewArrayBuffer(cx, len));
35 if (!buffer) {
36 return nullptr;
38 return JS_NewDataView(cx, buffer, 0, len);
41 template <class T>
42 struct InternalType {
43 using Type = uint8_t;
46 #define INT_TYPE(ExternalType, NativeType, Name) \
47 template <> \
48 struct InternalType<JS::TypedArray<js::Scalar::Name>> { \
49 using Type = NativeType; \
51 JS_FOR_EACH_TYPED_ARRAY(INT_TYPE)
52 #undef INT_TYPE
54 BEGIN_TEST(testArrayBufferView_type) {
55 CHECK((TestViewType<JS::TypedArray<Scalar::Uint8>, 7, 7>(cx)));
56 CHECK((TestViewType<JS::TypedArray<Scalar::Int8>, 33, 33>(cx)));
57 CHECK((TestViewType<JS::TypedArray<Scalar::Uint8Clamped>, 7, 7>(cx)));
58 CHECK((TestViewType<JS::TypedArray<Scalar::Uint16>, 3, 6>(cx)));
59 CHECK((TestViewType<JS::TypedArray<Scalar::Int16>, 17, 34>(cx)));
60 CHECK((TestViewType<JS::TypedArray<Scalar::Uint32>, 15, 60>(cx)));
61 CHECK((TestViewType<JS::TypedArray<Scalar::Int32>, 8, 32>(cx)));
62 CHECK((TestViewType<JS::TypedArray<Scalar::Float32>, 7, 28>(cx)));
63 CHECK((TestViewType<JS::TypedArray<Scalar::Float64>, 9, 72>(cx)));
64 CHECK((TestViewType<JS::DataView, 8, 8>(cx)));
66 return true;
69 template <class T>
70 struct ScalarTypeOf {
71 static constexpr js::Scalar::Type value = js::Scalar::MaxTypedArrayViewType;
74 template <js::Scalar::Type EType>
75 struct ScalarTypeOf<JS::TypedArray<EType>> {
76 static constexpr js::Scalar::Type value = EType;
78 template <class ViewType, uint32_t ExpectedLength, uint32_t ExpectedByteLength>
79 bool TestViewType(JSContext* cx) {
80 JS::Rooted<JSObject*> obj(cx, Create<ViewType>(cx, ExpectedLength));
81 CHECK(obj);
83 CHECK(JS_IsArrayBufferViewObject(obj));
85 CHECK(JS_GetArrayBufferViewByteLength(obj) == ExpectedByteLength);
88 JS::AutoCheckCannotGC nogc;
89 bool shared1;
90 JSObject* unwrapped = js::UnwrapArrayBufferView(obj);
91 uint8_t* data1 =
92 (uint8_t*)JS_GetArrayBufferViewData(unwrapped, &shared1, nogc);
94 auto view = ViewType::unwrap(obj);
95 CHECK(JS_GetArrayBufferViewType(obj) == ScalarTypeOf<ViewType>::value);
97 if (JS_IsTypedArrayObject(unwrapped)) {
98 CHECK(unwrapped->as<TypedArrayObject>().type() ==
99 TypeIDOfType<typename InternalType<ViewType>::Type>::id);
102 bool shared2;
103 size_t len;
104 uint8_t* data2 =
105 reinterpret_cast<uint8_t*>(view.getLengthAndData(&len, &shared2, nogc));
106 CHECK(obj == view.asObject());
107 CHECK(data1 == data2);
108 CHECK(shared1 == shared2);
109 CHECK(len == ExpectedLength);
111 JS::Heap<ViewType> hv(view);
113 bool shared3;
114 size_t len3;
115 uint8_t* data3 =
116 reinterpret_cast<uint8_t*>(hv.getLengthAndData(&len3, &shared3, nogc));
117 CHECK(obj == hv.asObject());
118 CHECK(data1 == data3);
119 CHECK(shared1 == shared3);
120 CHECK(len3 == ExpectedLength);
123 JS::RealmOptions options;
124 JS::RootedObject otherGlobal(
125 cx, JS_NewGlobalObject(cx, basicGlobalClass(), nullptr,
126 JS::DontFireOnNewGlobalHook, options));
127 CHECK(otherGlobal);
129 JS::Rooted<JSObject*> buffer(cx);
131 AutoRealm ar(cx, otherGlobal);
132 buffer = JS::NewArrayBuffer(cx, 8);
133 CHECK(buffer);
134 CHECK(buffer->as<ArrayBufferObject>().byteLength() == 8);
136 CHECK(buffer->compartment() == otherGlobal->compartment());
137 CHECK(JS_WrapObject(cx, &buffer));
138 CHECK(buffer->compartment() == global->compartment());
140 JS::Rooted<JSObject*> dataview(cx, JS_NewDataView(cx, buffer, 4, 4));
141 CHECK(dataview);
142 CHECK(dataview->is<ProxyObject>());
144 JS::Rooted<JS::Value> val(cx);
146 val = ObjectValue(*dataview);
147 CHECK(JS_SetProperty(cx, global, "view", val));
149 EVAL("view.buffer", &val);
150 CHECK(val.toObject().is<ProxyObject>());
152 CHECK(dataview->compartment() == global->compartment());
153 JS::Rooted<JSObject*> otherView(cx, js::UncheckedUnwrap(dataview));
154 CHECK(otherView->compartment() == otherGlobal->compartment());
155 JS::Rooted<JSObject*> otherBuffer(cx, js::UncheckedUnwrap(&val.toObject()));
156 CHECK(otherBuffer->compartment() == otherGlobal->compartment());
158 EVAL("Object.getPrototypeOf(view) === DataView.prototype", &val);
159 CHECK(val.toBoolean() == true);
161 return true;
164 END_TEST(testArrayBufferView_type)