1 : #include "tests.h"
2 :
3 : #include "jsclass.h"
4 :
5 : int count = 0;
6 :
7 : static JSBool
8 101 : IterNext(JSContext *cx, unsigned argc, jsval *vp)
9 : {
10 101 : if (count++ == 100)
11 1 : return JS_ThrowStopIteration(cx);
12 100 : JS_SET_RVAL(cx, vp, INT_TO_JSVAL(count));
13 100 : return true;
14 : }
15 :
16 : static JSObject *
17 1 : IterHook(JSContext *cx, JSObject *obj, JSBool keysonly)
18 : {
19 1 : JSObject *iterObj = JS_NewObject(cx, NULL, NULL, NULL);
20 1 : if (!iterObj)
21 0 : return NULL;
22 1 : if (!JS_DefineFunction(cx, iterObj, "next", IterNext, 0, 0))
23 0 : return NULL;
24 1 : return iterObj;
25 : }
26 :
27 : js::Class HasCustomIterClass = {
28 : "HasCustomIter",
29 : 0,
30 : JS_PropertyStub,
31 : JS_PropertyStub,
32 : JS_PropertyStub,
33 : JS_StrictPropertyStub,
34 : JS_EnumerateStub,
35 : JS_ResolveStub,
36 : JS_ConvertStub,
37 : NULL,
38 : NULL, /* checkAccess */
39 : NULL, /* call */
40 : NULL, /* construct */
41 : NULL, /* hasInstance */
42 : NULL, /* mark */
43 : {
44 : NULL,
45 : NULL,
46 : NULL,
47 : IterHook,
48 : NULL
49 : }
50 : };
51 :
52 : JSBool
53 1 : IterClassConstructor(JSContext *cx, unsigned argc, jsval *vp)
54 : {
55 1 : JSObject *obj = JS_NewObjectForConstructor(cx, vp);
56 1 : if (!obj)
57 0 : return false;
58 1 : JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
59 1 : return true;
60 : }
61 :
62 4 : BEGIN_TEST(testCustomIterator_bug612523)
63 : {
64 1 : CHECK(JS_InitClass(cx, JS_GetGlobalObject(cx), NULL, Jsvalify(&HasCustomIterClass),
65 : IterClassConstructor, 0, NULL, NULL, NULL, NULL));
66 :
67 : jsval result;
68 1 : EVAL("var o = new HasCustomIter(); \n"
69 : "var j = 0; \n"
70 : "for (var i in o) { ++j; }; \n"
71 : "j;", &result);
72 :
73 1 : CHECK(JSVAL_IS_INT(result));
74 1 : CHECK_EQUAL(JSVAL_TO_INT(result), 100);
75 1 : CHECK_EQUAL(count, 101);
76 :
77 1 : return true;
78 : }
79 2 : END_TEST(testCustomIterator_bug612523)
|