|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #include "js/Class.h" |
|
6 #include "jsapi-tests/tests.h" |
|
7 |
|
8 static int iterCount = 0; |
|
9 |
|
10 static bool |
|
11 IterNext(JSContext *cx, unsigned argc, jsval *vp) |
|
12 { |
|
13 JS::CallArgs args = JS::CallArgsFromVp(argc, vp); |
|
14 if (iterCount++ == 100) |
|
15 return JS_ThrowStopIteration(cx); |
|
16 args.rval().setInt32(iterCount); |
|
17 return true; |
|
18 } |
|
19 |
|
20 static JSObject * |
|
21 IterHook(JSContext *cx, JS::HandleObject obj, bool keysonly) |
|
22 { |
|
23 JS::RootedObject iterObj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr())); |
|
24 if (!iterObj) |
|
25 return nullptr; |
|
26 if (!JS_DefineFunction(cx, iterObj, "next", IterNext, 0, 0)) |
|
27 return nullptr; |
|
28 return iterObj; |
|
29 } |
|
30 |
|
31 const js::Class HasCustomIterClass = { |
|
32 "HasCustomIter", |
|
33 0, |
|
34 JS_PropertyStub, |
|
35 JS_DeletePropertyStub, |
|
36 JS_PropertyStub, |
|
37 JS_StrictPropertyStub, |
|
38 JS_EnumerateStub, |
|
39 JS_ResolveStub, |
|
40 JS_ConvertStub, |
|
41 nullptr, |
|
42 nullptr, /* call */ |
|
43 nullptr, /* hasInstance */ |
|
44 nullptr, /* construct */ |
|
45 nullptr, /* mark */ |
|
46 JS_NULL_CLASS_SPEC, |
|
47 { |
|
48 nullptr, /* outerObject */ |
|
49 nullptr, /* innerObject */ |
|
50 IterHook, |
|
51 false /* isWrappedNative */ |
|
52 } |
|
53 }; |
|
54 |
|
55 static bool |
|
56 IterClassConstructor(JSContext *cx, unsigned argc, jsval *vp) |
|
57 { |
|
58 JS::CallArgs args = JS::CallArgsFromVp(argc, vp); |
|
59 JSObject *obj = JS_NewObjectForConstructor(cx, Jsvalify(&HasCustomIterClass), args); |
|
60 if (!obj) |
|
61 return false; |
|
62 args.rval().setObject(*obj); |
|
63 return true; |
|
64 } |
|
65 |
|
66 BEGIN_TEST(testCustomIterator_bug612523) |
|
67 { |
|
68 CHECK(JS_InitClass(cx, global, js::NullPtr(), Jsvalify(&HasCustomIterClass), |
|
69 IterClassConstructor, 0, nullptr, nullptr, nullptr, nullptr)); |
|
70 |
|
71 JS::RootedValue result(cx); |
|
72 EVAL("var o = new HasCustomIter(); \n" |
|
73 "var j = 0; \n" |
|
74 "for (var i in o) { ++j; }; \n" |
|
75 "j;", &result); |
|
76 |
|
77 CHECK(JSVAL_IS_INT(result)); |
|
78 CHECK_EQUAL(JSVAL_TO_INT(result), 100); |
|
79 CHECK_EQUAL(iterCount, 101); |
|
80 |
|
81 return true; |
|
82 } |
|
83 END_TEST(testCustomIterator_bug612523) |