tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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)