|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * vim: set ts=8 sts=4 et sw=4 tw=99: |
|
3 */ |
|
4 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
7 |
|
8 #include "jsapi-tests/tests.h" |
|
9 |
|
10 static bool |
|
11 constructHook(JSContext *cx, unsigned argc, jsval *vp) |
|
12 { |
|
13 JS::CallArgs args = CallArgsFromVp(argc, vp); |
|
14 |
|
15 // Check that arguments were passed properly from JS_New. |
|
16 |
|
17 JS::RootedObject obj(cx, JS_NewObject(cx, js::Jsvalify(&JSObject::class_), JS::NullPtr(), JS::NullPtr())); |
|
18 if (!obj) { |
|
19 JS_ReportError(cx, "test failed, could not construct object"); |
|
20 return false; |
|
21 } |
|
22 if (strcmp(JS_GetClass(obj)->name, "Object") != 0) { |
|
23 JS_ReportError(cx, "test failed, wrong class for 'this'"); |
|
24 return false; |
|
25 } |
|
26 if (args.length() != 3) { |
|
27 JS_ReportError(cx, "test failed, argc == %d", args.length()); |
|
28 return false; |
|
29 } |
|
30 if (!args[0].isInt32() || args[2].toInt32() != 2) { |
|
31 JS_ReportError(cx, "test failed, wrong value in args[2]"); |
|
32 return false; |
|
33 } |
|
34 if (!args.isConstructing()) { |
|
35 JS_ReportError(cx, "test failed, not constructing"); |
|
36 return false; |
|
37 } |
|
38 |
|
39 // Perform a side-effect to indicate that this hook was actually called. |
|
40 JS::RootedValue value(cx, args[0]); |
|
41 JS::RootedObject callee(cx, &args.callee()); |
|
42 if (!JS_SetElement(cx, callee, 0, value)) |
|
43 return false; |
|
44 |
|
45 args.rval().setObject(*obj); |
|
46 |
|
47 // trash the argv, perversely |
|
48 args[0].setUndefined(); |
|
49 args[1].setUndefined(); |
|
50 args[2].setUndefined(); |
|
51 |
|
52 return true; |
|
53 } |
|
54 |
|
55 BEGIN_TEST(testNewObject_1) |
|
56 { |
|
57 static const size_t N = 1000; |
|
58 JS::AutoValueVector argv(cx); |
|
59 CHECK(argv.resize(N)); |
|
60 |
|
61 JS::RootedValue v(cx); |
|
62 EVAL("Array", &v); |
|
63 JS::RootedObject Array(cx, JSVAL_TO_OBJECT(v)); |
|
64 |
|
65 // With no arguments. |
|
66 JS::RootedObject obj(cx, JS_New(cx, Array, JS::HandleValueArray::empty())); |
|
67 CHECK(obj); |
|
68 JS::RootedValue rt(cx, JS::ObjectValue(*obj)); |
|
69 CHECK(JS_IsArrayObject(cx, obj)); |
|
70 uint32_t len; |
|
71 CHECK(JS_GetArrayLength(cx, obj, &len)); |
|
72 CHECK_EQUAL(len, 0); |
|
73 |
|
74 // With one argument. |
|
75 argv[0].setInt32(4); |
|
76 obj = JS_New(cx, Array, JS::HandleValueArray::subarray(argv, 0, 1)); |
|
77 CHECK(obj); |
|
78 rt = OBJECT_TO_JSVAL(obj); |
|
79 CHECK(JS_IsArrayObject(cx, obj)); |
|
80 CHECK(JS_GetArrayLength(cx, obj, &len)); |
|
81 CHECK_EQUAL(len, 4); |
|
82 |
|
83 // With N arguments. |
|
84 for (size_t i = 0; i < N; i++) |
|
85 argv[i].setInt32(i); |
|
86 obj = JS_New(cx, Array, JS::HandleValueArray::subarray(argv, 0, N)); |
|
87 CHECK(obj); |
|
88 rt = OBJECT_TO_JSVAL(obj); |
|
89 CHECK(JS_IsArrayObject(cx, obj)); |
|
90 CHECK(JS_GetArrayLength(cx, obj, &len)); |
|
91 CHECK_EQUAL(len, N); |
|
92 CHECK(JS_GetElement(cx, obj, N - 1, &v)); |
|
93 CHECK_SAME(v, INT_TO_JSVAL(N - 1)); |
|
94 |
|
95 // With JSClass.construct. |
|
96 static const JSClass cls = { |
|
97 "testNewObject_1", |
|
98 0, |
|
99 JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub, |
|
100 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, nullptr, |
|
101 nullptr, nullptr, constructHook |
|
102 }; |
|
103 JS::RootedObject ctor(cx, JS_NewObject(cx, &cls, JS::NullPtr(), JS::NullPtr())); |
|
104 CHECK(ctor); |
|
105 JS::RootedValue rt2(cx, OBJECT_TO_JSVAL(ctor)); |
|
106 obj = JS_New(cx, ctor, JS::HandleValueArray::subarray(argv, 0, 3)); |
|
107 CHECK(obj); |
|
108 CHECK(JS_GetElement(cx, ctor, 0, &v)); |
|
109 CHECK_SAME(v, JSVAL_ZERO); |
|
110 |
|
111 return true; |
|
112 } |
|
113 END_TEST(testNewObject_1) |