/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "tests.h"

using namespace JS;

static JSClass CustomClass = {
  "CustomClass",
  JSCLASS_HAS_RESERVED_SLOTS(1),
  JS_PropertyStub,
  JS_DeletePropertyStub,
  JS_PropertyStub,
  JS_StrictPropertyStub,
  JS_EnumerateStub,
  JS_ResolveStub,
  JS_ConvertStub
};

static const uint32_t CUSTOM_SLOT = 0;

static bool
IsCustomClass(const Value &v)
{
  return v.isObject() && JS_GetClass(&v.toObject()) == &CustomClass;
}

static bool
CustomMethodImpl(JSContext *cx, CallArgs args)
{
  JS_ASSERT(IsCustomClass(args.thisv()));
  args.rval().set(JS_GetReservedSlot(&args.thisv().toObject(), CUSTOM_SLOT));
  return true;
}

static JSBool
CustomMethod(JSContext *cx, unsigned argc, Value *vp)
{
  CallArgs args = CallArgsFromVp(argc, vp);
  return CallNonGenericMethod(cx, IsCustomClass, CustomMethodImpl, args);
}

BEGIN_TEST(test_CallNonGenericMethodOnProxy)
{
  // Create the first global object and compartment
  JS::RootedObject globalA(cx, JS_NewGlobalObject(cx, getGlobalClass(), NULL));
  CHECK(globalA);

  JS::RootedObject customA(cx, JS_NewObject(cx, &CustomClass, NULL, NULL));
  CHECK(customA);
  JS_SetReservedSlot(customA, CUSTOM_SLOT, Int32Value(17));

  JSFunction *customMethodA = JS_NewFunction(cx, CustomMethod, 0, 0, customA, "customMethodA");
  CHECK(customMethodA);

  JS::RootedValue rval(cx);
  CHECK(JS_CallFunction(cx, customA, customMethodA, 0, NULL, rval.address()));
  CHECK_SAME(rval, Int32Value(17));

  // Now create the second global object and compartment...
  {
    JS::RootedObject globalB(cx, JS_NewGlobalObject(cx, getGlobalClass(), NULL));
    CHECK(globalB);

    // ...and enter it.
    JSAutoCompartment enter(cx, globalB);
    JS::RootedObject customB(cx, JS_NewObject(cx, &CustomClass, NULL, NULL));
    CHECK(customB);
    JS_SetReservedSlot(customB, CUSTOM_SLOT, Int32Value(42));

    JS::RootedFunction customMethodB(cx, JS_NewFunction(cx, CustomMethod, 0, 0, customB, "customMethodB"));
    CHECK(customMethodB);

    JS::RootedValue rval(cx);
    CHECK(JS_CallFunction(cx, customB, customMethodB, 0, NULL, rval.address()));
    CHECK_SAME(rval, Int32Value(42));

    JS::RootedObject wrappedCustomA(cx, customA);
    CHECK(JS_WrapObject(cx, wrappedCustomA.address()));

    JS::RootedValue rval2(cx);
    CHECK(JS_CallFunction(cx, wrappedCustomA, customMethodB, 0, NULL, rval2.address()));
    CHECK_SAME(rval, Int32Value(42));
  }

  return true;
}
END_TEST(test_CallNonGenericMethodOnProxy)
