testArrayBufferOrViewAPI.cpp (3621B)
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 */ 4 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/. */ 8 9 #include <type_traits> 10 11 #include "jsfriendapi.h" 12 13 #include "js/ArrayBuffer.h" // JS::NewArrayBuffer 14 #include "js/experimental/TypedData.h" 15 #include "js/ScalarType.h" // JS::Scalar::Type 16 #include "jsapi-tests/tests.h" 17 18 #include "vm/Realm-inl.h" 19 20 using namespace js; 21 22 template <class ViewType> 23 static JSObject* CreateObj(JSContext* cx, size_t len) { 24 return ViewType::create(cx, len).asObject(); 25 } 26 27 template <> 28 JSObject* CreateObj<JS::DataView>(JSContext* cx, size_t len) { 29 JS::Rooted<JSObject*> buffer(cx, JS::NewArrayBuffer(cx, len)); 30 if (!buffer) { 31 return nullptr; 32 } 33 return JS_NewDataView(cx, buffer, 0, len); 34 } 35 36 BEGIN_TEST(testArrayBufferOrView_type) { 37 JS::RealmOptions options; 38 JS::RootedObject otherGlobal( 39 cx, JS_NewGlobalObject(cx, basicGlobalClass(), nullptr, 40 JS::DontFireOnNewGlobalHook, options)); 41 CHECK(otherGlobal); 42 43 CHECK((TestType<JS::TypedArray<Scalar::Uint8>>(cx, otherGlobal))); 44 CHECK((TestType<JS::TypedArray<Scalar::Int8>>(cx, otherGlobal))); 45 CHECK((TestType<JS::TypedArray<Scalar::Uint8Clamped>>(cx, otherGlobal))); 46 CHECK((TestType<JS::TypedArray<Scalar::Uint16>>(cx, otherGlobal))); 47 CHECK((TestType<JS::TypedArray<Scalar::Int16>>(cx, otherGlobal))); 48 CHECK((TestType<JS::TypedArray<Scalar::Uint32>>(cx, otherGlobal))); 49 CHECK((TestType<JS::TypedArray<Scalar::Int32>>(cx, otherGlobal))); 50 CHECK((TestType<JS::TypedArray<Scalar::Float32>>(cx, otherGlobal))); 51 CHECK((TestType<JS::TypedArray<Scalar::Float64>>(cx, otherGlobal))); 52 CHECK((TestType<JS::DataView>(cx, otherGlobal))); 53 CHECK((TestType<JS::ArrayBuffer>(cx, otherGlobal))); 54 55 return true; 56 } 57 58 template <class APIType> 59 bool TestType(JSContext* cx, Handle<JSObject*> otherGlobal) { 60 JS::Rooted<JSObject*> obj(cx, CreateObj<APIType>(cx, 8)); 61 CHECK(obj); 62 63 // Any of these should be creatable as an ArrayBufferOrView. 64 JS::Rooted<JS::ArrayBufferOrView> abov( 65 cx, JS::ArrayBufferOrView::fromObject(obj)); 66 CHECK(abov); 67 68 // And that should allow unwrapping as well. 69 abov = JS::ArrayBufferOrView::unwrap(obj); 70 CHECK(abov); 71 72 if constexpr (!std::is_same_v<APIType, JS::Uint16Array>) { 73 // Check that we can't make an API object of a different type. 74 JS::Rooted<JS::Uint16Array> nope(cx, JS::Uint16Array::unwrap(obj)); 75 CHECK(!nope); 76 77 // And that we can't make an API object from an object of a different type. 78 JS::Rooted<JSObject*> u16array(cx, CreateObj<JS::Uint16Array>(cx, 10)); 79 CHECK(u16array); 80 auto deny = APIType::fromObject(u16array); 81 CHECK(!deny); 82 deny = APIType::unwrap(u16array); 83 CHECK(!deny); 84 } 85 86 CHECK_EQUAL(abov.asObject(), obj); 87 88 JS::Rooted<JSObject*> wrapped(cx); 89 { 90 AutoRealm ar(cx, otherGlobal); 91 wrapped = CreateObj<APIType>(cx, 8); // Not wrapped yet! 92 CHECK(wrapped); 93 } 94 CHECK(wrapped->compartment() == otherGlobal->compartment()); 95 CHECK(JS_WrapObject(cx, &wrapped)); // Now it's wrapped. 96 CHECK(wrapped->compartment() == global->compartment()); 97 98 abov = JS::ArrayBufferOrView::fromObject(wrapped); 99 CHECK(!abov); 100 abov = JS::ArrayBufferOrView::unwrap(wrapped); 101 CHECK(abov); 102 103 JS::Rooted<APIType> dummy(cx, APIType::fromObject(obj)); 104 CHECK(obj); 105 CHECK(dummy); 106 CHECK(dummy.asObject()); 107 108 return true; 109 } 110 111 END_TEST(testArrayBufferOrView_type)