michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "jsapi-tests/tests.h" michael@0: michael@0: static bool michael@0: constructHook(JSContext *cx, unsigned argc, jsval *vp) michael@0: { michael@0: JS::CallArgs args = CallArgsFromVp(argc, vp); michael@0: michael@0: // Check that arguments were passed properly from JS_New. michael@0: michael@0: JS::RootedObject obj(cx, JS_NewObject(cx, js::Jsvalify(&JSObject::class_), JS::NullPtr(), JS::NullPtr())); michael@0: if (!obj) { michael@0: JS_ReportError(cx, "test failed, could not construct object"); michael@0: return false; michael@0: } michael@0: if (strcmp(JS_GetClass(obj)->name, "Object") != 0) { michael@0: JS_ReportError(cx, "test failed, wrong class for 'this'"); michael@0: return false; michael@0: } michael@0: if (args.length() != 3) { michael@0: JS_ReportError(cx, "test failed, argc == %d", args.length()); michael@0: return false; michael@0: } michael@0: if (!args[0].isInt32() || args[2].toInt32() != 2) { michael@0: JS_ReportError(cx, "test failed, wrong value in args[2]"); michael@0: return false; michael@0: } michael@0: if (!args.isConstructing()) { michael@0: JS_ReportError(cx, "test failed, not constructing"); michael@0: return false; michael@0: } michael@0: michael@0: // Perform a side-effect to indicate that this hook was actually called. michael@0: JS::RootedValue value(cx, args[0]); michael@0: JS::RootedObject callee(cx, &args.callee()); michael@0: if (!JS_SetElement(cx, callee, 0, value)) michael@0: return false; michael@0: michael@0: args.rval().setObject(*obj); michael@0: michael@0: // trash the argv, perversely michael@0: args[0].setUndefined(); michael@0: args[1].setUndefined(); michael@0: args[2].setUndefined(); michael@0: michael@0: return true; michael@0: } michael@0: michael@0: BEGIN_TEST(testNewObject_1) michael@0: { michael@0: static const size_t N = 1000; michael@0: JS::AutoValueVector argv(cx); michael@0: CHECK(argv.resize(N)); michael@0: michael@0: JS::RootedValue v(cx); michael@0: EVAL("Array", &v); michael@0: JS::RootedObject Array(cx, JSVAL_TO_OBJECT(v)); michael@0: michael@0: // With no arguments. michael@0: JS::RootedObject obj(cx, JS_New(cx, Array, JS::HandleValueArray::empty())); michael@0: CHECK(obj); michael@0: JS::RootedValue rt(cx, JS::ObjectValue(*obj)); michael@0: CHECK(JS_IsArrayObject(cx, obj)); michael@0: uint32_t len; michael@0: CHECK(JS_GetArrayLength(cx, obj, &len)); michael@0: CHECK_EQUAL(len, 0); michael@0: michael@0: // With one argument. michael@0: argv[0].setInt32(4); michael@0: obj = JS_New(cx, Array, JS::HandleValueArray::subarray(argv, 0, 1)); michael@0: CHECK(obj); michael@0: rt = OBJECT_TO_JSVAL(obj); michael@0: CHECK(JS_IsArrayObject(cx, obj)); michael@0: CHECK(JS_GetArrayLength(cx, obj, &len)); michael@0: CHECK_EQUAL(len, 4); michael@0: michael@0: // With N arguments. michael@0: for (size_t i = 0; i < N; i++) michael@0: argv[i].setInt32(i); michael@0: obj = JS_New(cx, Array, JS::HandleValueArray::subarray(argv, 0, N)); michael@0: CHECK(obj); michael@0: rt = OBJECT_TO_JSVAL(obj); michael@0: CHECK(JS_IsArrayObject(cx, obj)); michael@0: CHECK(JS_GetArrayLength(cx, obj, &len)); michael@0: CHECK_EQUAL(len, N); michael@0: CHECK(JS_GetElement(cx, obj, N - 1, &v)); michael@0: CHECK_SAME(v, INT_TO_JSVAL(N - 1)); michael@0: michael@0: // With JSClass.construct. michael@0: static const JSClass cls = { michael@0: "testNewObject_1", michael@0: 0, michael@0: JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub, michael@0: JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, nullptr, michael@0: nullptr, nullptr, constructHook michael@0: }; michael@0: JS::RootedObject ctor(cx, JS_NewObject(cx, &cls, JS::NullPtr(), JS::NullPtr())); michael@0: CHECK(ctor); michael@0: JS::RootedValue rt2(cx, OBJECT_TO_JSVAL(ctor)); michael@0: obj = JS_New(cx, ctor, JS::HandleValueArray::subarray(argv, 0, 3)); michael@0: CHECK(obj); michael@0: CHECK(JS_GetElement(cx, ctor, 0, &v)); michael@0: CHECK_SAME(v, JSVAL_ZERO); michael@0: michael@0: return true; michael@0: } michael@0: END_TEST(testNewObject_1)