testBug604087.cpp (3278B)
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 * Tests JS_TransplantObject 5 */ 6 /* This Source Code Form is subject to the terms of the Mozilla Public 7 * License, v. 2.0. If a copy of the MPL was not distributed with this 8 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 9 10 #include "js/friend/WindowProxy.h" // js::SetWindowProxyClass 11 #include "js/GlobalObject.h" // JS_NewGlobalObject 12 #include "js/Wrapper.h" 13 #include "js/WrapperCallbacks.h" 14 #include "jsapi-tests/tests.h" 15 #include "vm/JSObject.h" 16 #include "vm/ProxyObject.h" 17 18 const JSClass OuterWrapperClass = PROXY_CLASS_DEF( 19 "Proxy", JSCLASS_HAS_RESERVED_SLOTS(1) /* additional class flags */); 20 21 static JSObject* wrap(JSContext* cx, JS::HandleObject toWrap, 22 JS::HandleObject target) { 23 JSAutoRealm ar(cx, target); 24 JS::RootedObject wrapper(cx, toWrap); 25 if (!JS_WrapObject(cx, &wrapper)) { 26 return nullptr; 27 } 28 return wrapper; 29 } 30 31 static void PreWrap(JSContext* cx, JS::HandleObject scope, 32 JS::HandleObject origObj, JS::HandleObject obj, 33 JS::HandleObject objectPassedToWrap, 34 JS::MutableHandleObject retObj) { 35 JS_GC(cx); 36 retObj.set(obj); 37 } 38 39 static JSObject* Wrap(JSContext* cx, JS::HandleObject existing, 40 JS::HandleObject obj) { 41 return js::Wrapper::New(cx, obj, &js::CrossCompartmentWrapper::singleton); 42 } 43 44 static const JSWrapObjectCallbacks WrapObjectCallbacks = {Wrap, PreWrap}; 45 46 BEGIN_TEST(testBug604087) { 47 js::SetWindowProxyClass(cx, &OuterWrapperClass); 48 49 js::WrapperOptions options; 50 options.setClass(&OuterWrapperClass); 51 JS::RootedObject outerObj( 52 cx, js::Wrapper::New(cx, global, &js::Wrapper::singleton, options)); 53 JS::RealmOptions globalOptions; 54 JS::RootedObject compartment2( 55 cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, 56 JS::FireOnNewGlobalHook, globalOptions)); 57 CHECK(compartment2 != nullptr); 58 JS::RootedObject compartment3( 59 cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, 60 JS::FireOnNewGlobalHook, globalOptions)); 61 CHECK(compartment3 != nullptr); 62 JS::RootedObject compartment4( 63 cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, 64 JS::FireOnNewGlobalHook, globalOptions)); 65 CHECK(compartment4 != nullptr); 66 67 JS::RootedObject c2wrapper(cx, wrap(cx, outerObj, compartment2)); 68 CHECK(c2wrapper); 69 c2wrapper->as<js::ProxyObject>().setReservedSlot(0, js::Int32Value(2)); 70 71 JS::RootedObject c3wrapper(cx, wrap(cx, outerObj, compartment3)); 72 CHECK(c3wrapper); 73 c3wrapper->as<js::ProxyObject>().setReservedSlot(0, js::Int32Value(3)); 74 75 JS::RootedObject c4wrapper(cx, wrap(cx, outerObj, compartment4)); 76 CHECK(c4wrapper); 77 c4wrapper->as<js::ProxyObject>().setReservedSlot(0, js::Int32Value(4)); 78 compartment4 = c4wrapper = nullptr; 79 80 JS::RootedObject next(cx); 81 { 82 JSAutoRealm ar(cx, compartment2); 83 next = js::Wrapper::New(cx, compartment2, &js::Wrapper::singleton, options); 84 CHECK(next); 85 } 86 87 JS_SetWrapObjectCallbacks(cx, &WrapObjectCallbacks); 88 CHECK(JS_TransplantObject(cx, outerObj, next)); 89 return true; 90 } 91 END_TEST(testBug604087)