1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sw=4 et tw=99:
3 : */
4 :
5 : #include "tests.h"
6 :
7 : #include "jsfriendapi.h"
8 :
9 : const size_t N = 1000;
10 : static jsval argv[N];
11 :
12 : static JSBool
13 1 : constructHook(JSContext *cx, unsigned argc, jsval *vp)
14 : {
15 : // Check that arguments were passed properly from JS_New.
16 1 : JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
17 :
18 1 : JSObject *obj = JS_NewObjectForConstructor(cx, js::Jsvalify(&js::ObjectClass), vp);
19 1 : if (!obj) {
20 0 : JS_ReportError(cx, "test failed, could not construct object");
21 0 : return false;
22 : }
23 1 : if (strcmp(JS_GetClass(obj)->name, "Object") != 0) {
24 0 : JS_ReportError(cx, "test failed, wrong class for 'this'");
25 0 : return false;
26 : }
27 1 : if (argc != 3) {
28 0 : JS_ReportError(cx, "test failed, argc == %d", argc);
29 0 : return false;
30 : }
31 1 : if (!JSVAL_IS_INT(argv[2]) || JSVAL_TO_INT(argv[2]) != 2) {
32 0 : JS_ReportError(cx, "test failed, wrong value in argv[2]");
33 0 : return false;
34 : }
35 1 : if (!JS_IsConstructing(cx, vp)) {
36 0 : JS_ReportError(cx, "test failed, not constructing");
37 0 : return false;
38 : }
39 :
40 : // Perform a side-effect to indicate that this hook was actually called.
41 1 : if (!JS_SetElement(cx, callee, 0, &argv[0]))
42 0 : return false;
43 :
44 1 : *vp = OBJECT_TO_JSVAL(obj);
45 1 : argv[0] = argv[1] = argv[2] = JSVAL_VOID; // trash the argv, perversely
46 1 : return true;
47 : }
48 :
49 4 : BEGIN_TEST(testNewObject_1)
50 : {
51 : jsval v;
52 1 : EVAL("Array", &v);
53 1 : JSObject *Array = JSVAL_TO_OBJECT(v);
54 :
55 : // With no arguments.
56 1 : JSObject *obj = JS_New(cx, Array, 0, NULL);
57 1 : CHECK(obj);
58 2 : jsvalRoot rt(cx, OBJECT_TO_JSVAL(obj));
59 1 : CHECK(JS_IsArrayObject(cx, obj));
60 : uint32_t len;
61 1 : CHECK(JS_GetArrayLength(cx, obj, &len));
62 1 : CHECK_EQUAL(len, 0);
63 :
64 : // With one argument.
65 1 : argv[0] = INT_TO_JSVAL(4);
66 1 : obj = JS_New(cx, Array, 1, argv);
67 1 : CHECK(obj);
68 1 : rt = OBJECT_TO_JSVAL(obj);
69 1 : CHECK(JS_IsArrayObject(cx, obj));
70 1 : CHECK(JS_GetArrayLength(cx, obj, &len));
71 1 : CHECK_EQUAL(len, 4);
72 :
73 : // With N arguments.
74 1001 : for (size_t i = 0; i < N; i++)
75 1000 : argv[i] = INT_TO_JSVAL(i);
76 1 : obj = JS_New(cx, Array, N, argv);
77 1 : CHECK(obj);
78 1 : rt = OBJECT_TO_JSVAL(obj);
79 1 : CHECK(JS_IsArrayObject(cx, obj));
80 1 : CHECK(JS_GetArrayLength(cx, obj, &len));
81 1 : CHECK_EQUAL(len, N);
82 1 : CHECK(JS_GetElement(cx, obj, N - 1, &v));
83 1 : CHECK_SAME(v, INT_TO_JSVAL(N - 1));
84 :
85 : // With JSClass.construct.
86 : static JSClass cls = {
87 : "testNewObject_1",
88 : 0,
89 : JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
90 : JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL,
91 : NULL, NULL, constructHook
92 : };
93 1 : JSObject *ctor = JS_NewObject(cx, &cls, NULL, NULL);
94 1 : CHECK(ctor);
95 2 : jsvalRoot rt2(cx, OBJECT_TO_JSVAL(ctor));
96 1 : obj = JS_New(cx, ctor, 3, argv);
97 1 : CHECK(obj);
98 1 : CHECK(JS_GetElement(cx, ctor, 0, &v));
99 1 : CHECK_SAME(v, JSVAL_ZERO);
100 1 : return true;
101 : }
102 2 : END_TEST(testNewObject_1)
|