DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (a4e764f8dda4)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 */
/* 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 "jsapi-tests/tests.h"

static bool constructHook(JSContext* cx, unsigned argc, JS::Value* vp) {
  JS::CallArgs args = CallArgsFromVp(argc, vp);

  // Check that arguments were passed properly from JS_New.

  JS::RootedObject obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    JS_ReportErrorASCII(cx, "test failed, could not construct object");
    return false;
  }
  if (strcmp(JS_GetClass(obj)->name, "Object") != 0) {
    JS_ReportErrorASCII(cx, "test failed, wrong class for 'this'");
    return false;
  }
  if (args.length() != 3) {
    JS_ReportErrorASCII(cx, "test failed, argc == %d", args.length());
    return false;
  }
  if (!args[0].isInt32() || args[2].toInt32() != 2) {
    JS_ReportErrorASCII(cx, "test failed, wrong value in args[2]");
    return false;
  }
  if (!args.isConstructing()) {
    JS_ReportErrorASCII(cx, "test failed, not constructing");
    return false;
  }

  // Perform a side-effect to indicate that this hook was actually called.
  JS::RootedValue value(cx, args[0]);
  JS::RootedObject callee(cx, &args.callee());
  if (!JS_SetElement(cx, callee, 0, value)) {
    return false;
  }

  args.rval().setObject(*obj);

  // trash the argv, perversely
  args[0].setUndefined();
  args[1].setUndefined();
  args[2].setUndefined();

  return true;
}

BEGIN_TEST(testNewObject_1) {
  static const size_t N = 1000;
  JS::RootedValueVector argv(cx);
  CHECK(argv.resize(N));

  JS::RootedValue v(cx);
  EVAL("Array", &v);
  JS::RootedObject Array(cx, v.toObjectOrNull());

  bool isArray;

  // With no arguments.
  JS::RootedObject obj(cx, JS_New(cx, Array, JS::HandleValueArray::empty()));
  CHECK(obj);
  JS::RootedValue rt(cx, JS::ObjectValue(*obj));
  CHECK(JS_IsArrayObject(cx, obj, &isArray));
  CHECK(isArray);
  uint32_t len;
  CHECK(JS_GetArrayLength(cx, obj, &len));
  CHECK_EQUAL(len, 0u);

  // With one argument.
  argv[0].setInt32(4);
  obj = JS_New(cx, Array, JS::HandleValueArray::subarray(argv, 0, 1));
  CHECK(obj);
  rt = JS::ObjectValue(*obj);
  CHECK(JS_IsArrayObject(cx, obj, &isArray));
  CHECK(isArray);
  CHECK(JS_GetArrayLength(cx, obj, &len));
  CHECK_EQUAL(len, 4u);

  // With N arguments.
  for (size_t i = 0; i < N; i++) {
    argv[i].setInt32(i);
  }
  obj = JS_New(cx, Array, JS::HandleValueArray::subarray(argv, 0, N));
  CHECK(obj);
  rt = JS::ObjectValue(*obj);
  CHECK(JS_IsArrayObject(cx, obj, &isArray));
  CHECK(isArray);
  CHECK(JS_GetArrayLength(cx, obj, &len));
  CHECK_EQUAL(len, N);
  CHECK(JS_GetElement(cx, obj, N - 1, &v));
  CHECK(v.isInt32(N - 1));

  // With JSClass.construct.
  static const JSClassOps clsOps = {nullptr, nullptr,      nullptr, nullptr,
                                    nullptr, nullptr,      nullptr, nullptr,
                                    nullptr, constructHook};
  static const JSClass cls = {"testNewObject_1", 0, &clsOps};
  JS::RootedObject ctor(cx, JS_NewObject(cx, &cls));
  CHECK(ctor);
  JS::RootedValue rt2(cx, JS::ObjectValue(*ctor));
  obj = JS_New(cx, ctor, JS::HandleValueArray::subarray(argv, 0, 3));
  CHECK(obj);
  CHECK(JS_GetElement(cx, ctor, 0, &v));
  CHECK(v.isInt32(0));

  return true;
}
END_TEST(testNewObject_1)

BEGIN_TEST(testNewObject_IsMapObject) {
  // Test IsMapObject and IsSetObject

  JS::RootedValue vMap(cx);
  EVAL("Map", &vMap);
  JS::RootedObject Map(cx, vMap.toObjectOrNull());

  bool isMap = false;
  bool isSet = false;
  JS::RootedObject mapObj(cx, JS_New(cx, Map, JS::HandleValueArray::empty()));
  CHECK(mapObj);
  CHECK(JS::IsMapObject(cx, mapObj, &isMap));
  CHECK(isMap);
  CHECK(JS::IsSetObject(cx, mapObj, &isSet));
  CHECK(!isSet);

  JS::RootedValue vSet(cx);
  EVAL("Set", &vSet);
  JS::RootedObject Set(cx, vSet.toObjectOrNull());

  JS::RootedObject setObj(cx, JS_New(cx, Set, JS::HandleValueArray::empty()));
  CHECK(setObj);
  CHECK(JS::IsMapObject(cx, setObj, &isMap));
  CHECK(!isMap);
  CHECK(JS::IsSetObject(cx, setObj, &isSet));
  CHECK(isSet);

  return true;
}
END_TEST(testNewObject_IsMapObject)