testCallNonGenericMethodOnProxy.cpp (2967B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include "js/CallAndConstruct.h" 6 #include "js/GlobalObject.h" 7 #include "js/Object.h" // JS::GetClass, JS::GetReservedSlot 8 #include "jsapi-tests/tests.h" 9 10 using namespace JS; 11 12 static const JSClass CustomClass = { 13 "CustomClass", 14 JSCLASS_HAS_RESERVED_SLOTS(1), 15 }; 16 17 static const uint32_t CUSTOM_SLOT = 0; 18 19 static bool IsCustomClass(JS::Handle<JS::Value> v) { 20 return v.isObject() && JS::GetClass(&v.toObject()) == &CustomClass; 21 } 22 23 static bool CustomMethodImpl(JSContext* cx, const CallArgs& args) { 24 MOZ_RELEASE_ASSERT(IsCustomClass(args.thisv())); 25 args.rval().set(JS::GetReservedSlot(&args.thisv().toObject(), CUSTOM_SLOT)); 26 return true; 27 } 28 29 static bool CustomMethod(JSContext* cx, unsigned argc, Value* vp) { 30 CallArgs args = CallArgsFromVp(argc, vp); 31 return CallNonGenericMethod(cx, IsCustomClass, CustomMethodImpl, args); 32 } 33 34 BEGIN_TEST(test_CallNonGenericMethodOnProxy) { 35 // Create the first global object and compartment 36 JS::RealmOptions options; 37 JS::RootedObject globalA( 38 cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, 39 JS::FireOnNewGlobalHook, options)); 40 CHECK(globalA); 41 42 JS::RootedObject customA(cx, JS_NewObject(cx, &CustomClass)); 43 CHECK(customA); 44 JS_SetReservedSlot(customA, CUSTOM_SLOT, Int32Value(17)); 45 46 JS::RootedFunction customMethodA( 47 cx, JS_NewFunction(cx, CustomMethod, 0, 0, "customMethodA")); 48 CHECK(customMethodA); 49 50 JS::RootedValue rval(cx); 51 CHECK(JS_CallFunction(cx, customA, customMethodA, 52 JS::HandleValueArray::empty(), &rval)); 53 CHECK_SAME(rval, Int32Value(17)); 54 55 // Now create the second global object and compartment... 56 { 57 JS::RealmOptions options; 58 JS::RootedObject globalB( 59 cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, 60 JS::FireOnNewGlobalHook, options)); 61 CHECK(globalB); 62 63 // ...and enter it. 64 JSAutoRealm enter(cx, globalB); 65 JS::RootedObject customB(cx, JS_NewObject(cx, &CustomClass)); 66 CHECK(customB); 67 JS_SetReservedSlot(customB, CUSTOM_SLOT, Int32Value(42)); 68 69 JS::RootedFunction customMethodB( 70 cx, JS_NewFunction(cx, CustomMethod, 0, 0, "customMethodB")); 71 CHECK(customMethodB); 72 73 JS::RootedValue rval(cx); 74 CHECK(JS_CallFunction(cx, customB, customMethodB, 75 JS::HandleValueArray::empty(), &rval)); 76 CHECK_SAME(rval, Int32Value(42)); 77 78 JS::RootedObject wrappedCustomA(cx, customA); 79 CHECK(JS_WrapObject(cx, &wrappedCustomA)); 80 81 JS::RootedValue rval2(cx); 82 CHECK(JS_CallFunction(cx, wrappedCustomA, customMethodB, 83 JS::HandleValueArray::empty(), &rval2)); 84 CHECK_SAME(rval, Int32Value(42)); 85 } 86 87 return true; 88 } 89 END_TEST(test_CallNonGenericMethodOnProxy)