@@ -47,18 +47,47 @@ finalize(JSContext* jscx, JSObject* jsobj)
47
47
JSBool
48
48
call (JSContext * jscx , JSObject * jsobj , uintN argc , jsval * argv , jsval * rval )
49
49
{
50
+ jsval objval = argv [-2 ];
51
+ JSObject * obj = JSVAL_TO_OBJECT (objval );
52
+
53
+ if (argc >= 1 && JSVAL_IS_BOOLEAN (argv [0 ]) && !JSVAL_TO_BOOLEAN (argv [0 ]))
54
+ {
55
+ if (!JS_SetReservedSlot (jscx , obj , 2 , JSVAL_TRUE ))
56
+ {
57
+ JS_ReportError (jscx , "Failed to reset iterator flag." );
58
+ return JS_FALSE ;
59
+ }
60
+ }
61
+
50
62
* rval = argv [-2 ];
51
63
return JS_TRUE ;
52
64
}
53
65
66
+ JSBool
67
+ is_for_each (JSContext * cx , JSObject * obj , JSBool * rval )
68
+ {
69
+ jsval slot ;
70
+ if (!JS_GetReservedSlot (cx , obj , 2 , & slot ))
71
+ {
72
+ return JS_FALSE ;
73
+ }
74
+
75
+ if (!JSVAL_IS_BOOLEAN (slot )) return JS_FALSE ;
76
+ * rval = JSVAL_TO_BOOLEAN (slot );
77
+ return JS_TRUE ;
78
+ }
79
+
54
80
JSBool
55
81
def_next (JSContext * jscx , JSObject * jsobj , uintN argc , jsval * argv , jsval * rval )
56
82
{
57
83
Context * pycx = NULL ;
84
+ PyObject * pyobj = NULL ;
58
85
PyObject * iter = NULL ;
59
86
PyObject * next = NULL ;
87
+ PyObject * value = NULL ;
60
88
JSBool ret = JS_FALSE ;
61
-
89
+ JSBool foreach = JS_FALSE ;
90
+
62
91
// For StopIteration throw
63
92
JSObject * glbl = JS_GetGlobalObject (jscx );
64
93
jsval exc = JSVAL_VOID ;
@@ -77,6 +106,13 @@ def_next(JSContext* jscx, JSObject* jsobj, uintN argc, jsval* argv, jsval* rval)
77
106
goto done ;
78
107
}
79
108
109
+ pyobj = get_js_slot (jscx , jsobj , 0 );
110
+ if (pyobj == NULL )
111
+ {
112
+ JS_ReportError (jscx , "Failed to find iterated object." );
113
+ goto done ;
114
+ }
115
+
80
116
next = PyIter_Next (iter );
81
117
if (next == NULL && PyErr_Occurred ())
82
118
{
@@ -95,11 +131,33 @@ def_next(JSContext* jscx, JSObject* jsobj, uintN argc, jsval* argv, jsval* rval)
95
131
goto done ;
96
132
}
97
133
98
- * rval = py2js (pycx , next );
134
+ if (!is_for_each (jscx , jsobj , & foreach ))
135
+ {
136
+ JS_ReportError (jscx , "Failed to get iterator flag." );
137
+ goto done ;
138
+ }
139
+
140
+ if (PyMapping_Check (pyobj ) && foreach )
141
+ {
142
+ fprintf (stderr , "IS FOR EACH ON MAPPING\n" );
143
+ value = PyObject_GetItem (pyobj , next );
144
+ if (value == NULL )
145
+ {
146
+ JS_ReportError (jscx , "Failed to get value in 'for each'" );
147
+ goto done ;
148
+ }
149
+ * rval = py2js (pycx , value );
150
+ }
151
+ else
152
+ {
153
+ * rval = py2js (pycx , next );
154
+ }
155
+
99
156
if (* rval != JSVAL_VOID ) ret = JS_TRUE ;
100
157
101
158
done :
102
159
Py_XDECREF (next );
160
+ Py_XDECREF (value );
103
161
return ret ;
104
162
}
105
163
@@ -110,8 +168,9 @@ seq_next(JSContext* jscx, JSObject* jsobj, uintN argc, jsval* argv, jsval* rval)
110
168
PyObject * pyobj = NULL ;
111
169
PyObject * iter = NULL ;
112
170
PyObject * next = NULL ;
113
- JSObject * jsiter = NULL ;
171
+ PyObject * value = NULL ;
114
172
JSBool ret = JS_FALSE ;
173
+ JSBool foreach = JS_FALSE ;
115
174
long maxval = -1 ;
116
175
long currval = -1 ;
117
176
@@ -171,19 +230,41 @@ seq_next(JSContext* jscx, JSObject* jsobj, uintN argc, jsval* argv, jsval* rval)
171
230
goto done ;
172
231
}
173
232
174
- * rval = py2js (pycx , iter );
233
+ if (!is_for_each (jscx , jsobj , & foreach ))
234
+ {
235
+ JS_ReportError (jscx , "Failed to get iterator flag." );
236
+ goto done ;
237
+ }
238
+
239
+ if (foreach )
240
+ {
241
+ fprintf (stderr , "IS FOR EACH ON SEQUENCE\n" );
242
+ value = PyObject_GetItem (pyobj , iter );
243
+ if (value == NULL )
244
+ {
245
+ JS_ReportError (jscx , "Failed to get array element in 'for each'" );
246
+ goto done ;
247
+ }
248
+ * rval = py2js (pycx , value );
249
+ }
250
+ else
251
+ {
252
+ * rval = py2js (pycx , iter );
253
+ }
254
+
175
255
next = iter ;
176
256
if (* rval != JSVAL_VOID ) ret = JS_TRUE ;
177
257
178
258
done :
179
259
Py_XDECREF (next );
260
+ Py_XDECREF (value );
180
261
return ret ;
181
262
}
182
263
183
264
static JSClass
184
265
js_iter_class = {
185
266
"PyJSIteratorClass" ,
186
- JSCLASS_HAS_RESERVED_SLOTS (2 ),
267
+ JSCLASS_HAS_RESERVED_SLOTS (3 ),
187
268
JS_PropertyStub ,
188
269
JS_PropertyStub ,
189
270
JS_PropertyStub ,
@@ -264,6 +345,12 @@ new_py_def_iter(Context* cx, PyObject* obj, jsval* rval)
264
345
goto error ;
265
346
}
266
347
348
+ if (!JS_SetReservedSlot (cx -> cx , jsiter , 2 , JSVAL_FALSE ))
349
+ {
350
+ PyErr_SetString (PyExc_RuntimeError , "Failed to store iterator flag." );
351
+ goto error ;
352
+ }
353
+
267
354
Py_INCREF (cx );
268
355
* rval = OBJECT_TO_JSVAL (jsiter );
269
356
ret = JS_TRUE ;
@@ -317,6 +404,12 @@ new_py_seq_iter(Context* cx, PyObject* obj, jsval* rval)
317
404
goto error ;
318
405
}
319
406
407
+ if (!JS_SetReservedSlot (cx -> cx , jsiter , 2 , JSVAL_FALSE ))
408
+ {
409
+ PyErr_SetString (PyExc_RuntimeError , "Failed to store iterator flag." );
410
+ goto error ;
411
+ }
412
+
320
413
Py_INCREF (cx );
321
414
* rval = OBJECT_TO_JSVAL (jsiter );
322
415
ret = JS_TRUE ;
0 commit comments