1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,93 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "jsapi-tests/tests.h" 1.9 + 1.10 +using namespace JS; 1.11 + 1.12 +static const JSClass CustomClass = { 1.13 + "CustomClass", 1.14 + JSCLASS_HAS_RESERVED_SLOTS(1), 1.15 + JS_PropertyStub, 1.16 + JS_DeletePropertyStub, 1.17 + JS_PropertyStub, 1.18 + JS_StrictPropertyStub, 1.19 + JS_EnumerateStub, 1.20 + JS_ResolveStub, 1.21 + JS_ConvertStub 1.22 +}; 1.23 + 1.24 +static const uint32_t CUSTOM_SLOT = 0; 1.25 + 1.26 +static bool 1.27 +IsCustomClass(JS::Handle<JS::Value> v) 1.28 +{ 1.29 + return v.isObject() && JS_GetClass(&v.toObject()) == &CustomClass; 1.30 +} 1.31 + 1.32 +static bool 1.33 +CustomMethodImpl(JSContext *cx, CallArgs args) 1.34 +{ 1.35 + JS_ASSERT(IsCustomClass(args.thisv())); 1.36 + args.rval().set(JS_GetReservedSlot(&args.thisv().toObject(), CUSTOM_SLOT)); 1.37 + return true; 1.38 +} 1.39 + 1.40 +static bool 1.41 +CustomMethod(JSContext *cx, unsigned argc, Value *vp) 1.42 +{ 1.43 + CallArgs args = CallArgsFromVp(argc, vp); 1.44 + return CallNonGenericMethod(cx, IsCustomClass, CustomMethodImpl, args); 1.45 +} 1.46 + 1.47 +BEGIN_TEST(test_CallNonGenericMethodOnProxy) 1.48 +{ 1.49 + // Create the first global object and compartment 1.50 + JS::RootedObject globalA(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook)); 1.51 + CHECK(globalA); 1.52 + 1.53 + JS::RootedObject customA(cx, JS_NewObject(cx, &CustomClass, JS::NullPtr(), JS::NullPtr())); 1.54 + CHECK(customA); 1.55 + JS_SetReservedSlot(customA, CUSTOM_SLOT, Int32Value(17)); 1.56 + 1.57 + JS::RootedFunction customMethodA(cx, JS_NewFunction(cx, CustomMethod, 0, 0, 1.58 + customA, "customMethodA")); 1.59 + CHECK(customMethodA); 1.60 + 1.61 + JS::RootedValue rval(cx); 1.62 + CHECK(JS_CallFunction(cx, customA, customMethodA, JS::HandleValueArray::empty(), 1.63 + &rval)); 1.64 + CHECK_SAME(rval, Int32Value(17)); 1.65 + 1.66 + // Now create the second global object and compartment... 1.67 + { 1.68 + JS::RootedObject globalB(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook)); 1.69 + CHECK(globalB); 1.70 + 1.71 + // ...and enter it. 1.72 + JSAutoCompartment enter(cx, globalB); 1.73 + JS::RootedObject customB(cx, JS_NewObject(cx, &CustomClass, JS::NullPtr(), JS::NullPtr())); 1.74 + CHECK(customB); 1.75 + JS_SetReservedSlot(customB, CUSTOM_SLOT, Int32Value(42)); 1.76 + 1.77 + JS::RootedFunction customMethodB(cx, JS_NewFunction(cx, CustomMethod, 0, 0, customB, "customMethodB")); 1.78 + CHECK(customMethodB); 1.79 + 1.80 + JS::RootedValue rval(cx); 1.81 + CHECK(JS_CallFunction(cx, customB, customMethodB, JS::HandleValueArray::empty(), 1.82 + &rval)); 1.83 + CHECK_SAME(rval, Int32Value(42)); 1.84 + 1.85 + JS::RootedObject wrappedCustomA(cx, customA); 1.86 + CHECK(JS_WrapObject(cx, &wrappedCustomA)); 1.87 + 1.88 + JS::RootedValue rval2(cx); 1.89 + CHECK(JS_CallFunction(cx, wrappedCustomA, customMethodB, JS::HandleValueArray::empty(), 1.90 + &rval2)); 1.91 + CHECK_SAME(rval, Int32Value(42)); 1.92 + } 1.93 + 1.94 + return true; 1.95 +} 1.96 +END_TEST(test_CallNonGenericMethodOnProxy)