<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>spidermonkey/pyiter.c</filename>
    </added>
    <added>
      <filename>spidermonkey/pyiter.h</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,3 +1,3 @@
 #! /bin/bash
-python setup.py build
-gdb --command=go.comm --batch python2.5
+#python setup.py build
+gdb --command=go.comm --batch python</diff>
      <filename>go</filename>
    </modified>
    <modified>
      <diff>@@ -12,35 +12,39 @@ jsval
 py2js_integer(Context* cx, PyObject* obj)
 {
     long pyval;
-    jsval ret = JSVAL_VOID;
     
     if(PyInt_Check(obj))
     {
         pyval = PyInt_AsLong(obj);
-        if(PyErr_Occurred()) goto error;
+        if(PyErr_Occurred()) return JSVAL_VOID;
     }
     else
     {
         pyval = PyLong_AsLong(obj);
-        if(PyErr_Occurred()) goto error;
+        if(PyErr_Occurred()) return JSVAL_VOID;
     }
-    
+
+    return long2js_integer(cx, pyval);
+}
+
+jsval
+long2js_integer(Context* cx, long pyval)
+{
+    jsval ret = JSVAL_VOID;
+
     if(INT_FITS_IN_JSVAL(pyval))
     {
         ret = INT_TO_JSVAL(pyval);
-        goto success;
+        goto done;
     }
     
     if(!JS_NewNumberValue(cx-&gt;cx, pyval, &amp;ret))
     {
         PyErr_SetString(PyExc_ValueError, &quot;Failed to convert number.&quot;);
-        goto error;
+        goto done;
     }
 
-    goto success;
-
-error:
-success:
+done:
     return ret;
 }
 </diff>
      <filename>spidermonkey/integer.c</filename>
    </modified>
    <modified>
      <diff>@@ -10,6 +10,7 @@
 #define PYSM_INTEGER_H
 
 jsval py2js_integer(Context* cx, PyObject* obj);
+jsval long2js_integer(Context* cx, long val);
 PyObject* js2py_integer(Context* cx, jsval val);
 
 #endif</diff>
      <filename>spidermonkey/integer.h</filename>
    </modified>
    <modified>
      <diff>@@ -7,6 +7,7 @@
  */
 
 #include &quot;spidermonkey.h&quot;
+#include &quot;libjs/jsobj.h&quot;
 
 /*
     This is a fairly unsafe operation in so much as
@@ -82,21 +83,43 @@ js_get_prop(JSContext* jscx, JSObject* jsobj, jsval key, jsval* val)
     Context* pycx = NULL;
     PyObject* pyobj = NULL;
     PyObject* pykey = NULL;
+    PyObject* utf8 = NULL;
     PyObject* pyval = NULL;
     JSBool ret = JS_FALSE;
-   
+    const char* data;
+
     pycx = (Context*) JS_GetContextPrivate(jscx);
     if(pycx == NULL)
     {
         PyErr_SetString(PyExc_RuntimeError, &quot;Failed to get JS Context.&quot;);
-        goto error;
+        goto done;
     }
     
     pyobj = get_py_obj(jscx, jsobj);
-    if(pyobj == NULL) goto error;
+    if(pyobj == NULL) goto done;
     
     pykey = js2py(pycx, key);
-    if(pykey == NULL) goto error;
+    if(pykey == NULL) goto done;
+
+    utf8 = PyUnicode_AsUTF8String(pykey);
+    if(utf8 == NULL) goto done;
+
+    // Yeah. It's ugly as sin.
+    if(PyString_Check(utf8))
+    {
+        data = PyString_AsString(utf8);
+        if(data == NULL) goto done;
+
+        if(strcmp(&quot;__iterator__&quot;, data) == 0)
+        {
+            if(!new_py_iter(pycx, pyobj, val)) goto done;
+            if(*val != JSVAL_VOID)
+            {
+                ret = JS_TRUE;
+                goto done;
+            }
+        }
+    }
 
     pyval = PyObject_GetItem(pyobj, pykey);
     if(pyval == NULL)
@@ -108,20 +131,19 @@ js_get_prop(JSContext* jscx, JSObject* jsobj, jsval key, jsval* val)
             PyErr_Clear();
             ret = JS_TRUE;
             *val = JSVAL_VOID;
-            goto success;
+            goto done;
         }
     }
 
     *val = py2js(pycx, pyval);
-    if(*val == JSVAL_VOID) goto error;
+    if(*val == JSVAL_VOID) goto done;
     ret = JS_TRUE;
-    goto success;
 
-error:
-success:
+done:
     Py_XDECREF(pykey);
     Py_XDECREF(pyval);
-    
+    Py_XDECREF(utf8);
+
     return ret;
 }
 
@@ -178,18 +200,6 @@ success:
     return ret;
 }
 
-JSBool
-js_enumerate(JSContext* jscx, JSObject* jsobj)
-{
-    return JS_TRUE;
-}
-
-JSBool
-js_resolve(JSContext* cx, JSObject* obj, jsval key)
-{
-    return JS_TRUE;
-}
-
 void
 js_finalize(JSContext* jscx, JSObject* jsobj)
 {
@@ -355,14 +365,15 @@ success:
 }
 
 JSClass*
-create_class(Context* cx, PyTypeObject* type)
+create_class(Context* cx, PyObject* pyobj)
 {
     PyObject* curr = NULL;
     JSClass* jsclass = NULL;
     JSClass* ret = NULL;
     char* classname = NULL;
-    
-    curr = Context_get_class(cx, type-&gt;tp_name);
+    int flags = JSCLASS_HAS_RESERVED_SLOTS(1);
+
+    curr = Context_get_class(cx, pyobj-&gt;ob_type-&gt;tp_name);
     if(curr != NULL) return (JSClass*) HashCObj_AsVoidPtr(curr);
 
     jsclass = (JSClass*) malloc(sizeof(JSClass));
@@ -372,29 +383,28 @@ create_class(Context* cx, PyTypeObject* type)
         goto error;
     }
    
-    classname = (char*) malloc(strlen(type-&gt;tp_name)*sizeof(char));
+    classname = (char*) malloc(strlen(pyobj-&gt;ob_type-&gt;tp_name)*sizeof(char));
     if(classname == NULL)
     {
         PyErr_NoMemory();
         goto error;
     }
     
-    strcpy((char*) classname, type-&gt;tp_name);
+    strcpy((char*) classname, pyobj-&gt;ob_type-&gt;tp_name);
     jsclass-&gt;name = classname;
     
-    jsclass-&gt;flags = JSCLASS_HAS_RESERVED_SLOTS(1);
+    jsclass-&gt;flags = flags;
     jsclass-&gt;addProperty = js_add_prop;
     jsclass-&gt;delProperty = js_del_prop;
     jsclass-&gt;getProperty = js_get_prop;
     jsclass-&gt;setProperty = js_set_prop;
-    jsclass-&gt;enumerate = js_enumerate;
-    jsclass-&gt;resolve = js_resolve;
+    jsclass-&gt;enumerate = JS_EnumerateStub;
+    jsclass-&gt;resolve = JS_ResolveStub;
     jsclass-&gt;convert = JS_ConvertStub;
     jsclass-&gt;finalize = js_finalize;
     jsclass-&gt;getObjectOps = NULL;
     jsclass-&gt;checkAccess = NULL;
     jsclass-&gt;call = js_call;
-    //jsclass-&gt;construct = NULL;
     jsclass-&gt;construct = js_ctor;
     jsclass-&gt;xdrObject = NULL;
     jsclass-&gt;hasInstance = NULL;
@@ -403,7 +413,7 @@ create_class(Context* cx, PyTypeObject* type)
     
     curr = HashCObj_FromVoidPtr(jsclass);
     if(curr == NULL) goto error;
-    if(Context_add_class(cx, type-&gt;tp_name, curr) &lt; 0) goto error;
+    if(Context_add_class(cx, pyobj-&gt;ob_type-&gt;tp_name, curr) &lt; 0) goto error;
 
     ret = jsclass;
     goto success;
@@ -425,7 +435,7 @@ py2js_object(Context* cx, PyObject* pyobj)
     jsval pyval;
     jsval ret = JSVAL_VOID;
    
-    klass = create_class(cx, pyobj-&gt;ob_type);
+    klass = create_class(cx, pyobj);
     if(klass == NULL) goto error;
 
     jsobj = JS_NewObject(cx-&gt;cx, klass, NULL, NULL);
@@ -434,7 +444,8 @@ py2js_object(Context* cx, PyObject* pyobj)
         PyErr_SetString(PyExc_RuntimeError, &quot;Failed to create JS object.&quot;);
         goto error;
     }
-    
+
+    // do the attached = pyobj dance to only DECREF if we get passed INCREF
     attached = pyobj;
     // INCREF for the value stored in JS
     Py_INCREF(attached);</diff>
      <filename>spidermonkey/pyobject.c</filename>
    </modified>
    <modified>
      <diff>@@ -22,6 +22,7 @@
 #include &quot;double.h&quot;
 
 #include &quot;pyobject.h&quot;
+#include &quot;pyiter.h&quot;
 
 #include &quot;jsobject.h&quot;
 #include &quot;jsarray.h&quot;</diff>
      <filename>spidermonkey/spidermonkey.h</filename>
    </modified>
    <modified>
      <diff>@@ -4,26 +4,33 @@
 # under the MIT license.
 import t
 
-class Foo(object):
-    def __init__(self):
-        self.blam = 8
-        self.zing = &quot;yessiree&quot;
-
-@t.glbl(&quot;zip&quot;, Foo())
-def test_iter_py(cx, glbl):
-    js = &quot;&quot;&quot;
-        var ret = [];
-        for(var v in zip) {
-            ret.push(v)
-        }
-        ret;
-    &quot;&quot;&quot;
-    t.eq(cx.execute(js), [&quot;blam&quot;, &quot;zing&quot;])
-
-@t.cx()
-def test_iter_js(cx):
-    ret = cx.execute('var f = {&quot;foo&quot;: 1, &quot;domino&quot;: &quot;daily&quot;}; f;')
-    keys = [k for k in ret]
-    keys.sort()
-    t.eq(keys, [&quot;domino&quot;, &quot;foo&quot;])
+@t.rt()
+def test_iter_py(rt):
+    pairs = [
+        ({&quot;foo&quot;: &quot;bar&quot;, &quot;baz&quot;: &quot;bam&quot;}, [&quot;foo&quot;, &quot;baz&quot;]),
+        ([&quot;a&quot;, &quot;b&quot;, &quot;c&quot;], [0, 1, 2])
+    ]
+    def check(a, b):
+        cx = rt.new_context()
+        cx.add_global(&quot;zip&quot;, a)
+        js = &quot;&quot;&quot;
+            var ret = [];
+            for(var v in zip) {ret.push(v);}
+            ret;
+        &quot;&quot;&quot;
+        t.eq(cx.execute(js), b)
+    map(lambda x: check(*x), pairs)
 
+@t.rt()
+def test_iter_js(rt):
+    pairs = [
+        ('var f = {&quot;foo&quot;: 1, &quot;domino&quot;: &quot;daily&quot;}; f;', [&quot;domino&quot;, &quot;foo&quot;]),
+        ('[&quot;foo&quot;, 1, &quot;bing&quot;]', [0, 1, 2])
+    ]
+    def check(a, b):
+        cx = rt.new_context()
+        ret = cx.execute(a)
+        data = [k for k in ret]
+        data.sort()
+        t.eq(data, b)
+    map(lambda x: check(*x), pairs)</diff>
      <filename>tests/test-iterate.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>1a1300a296f7562e6ddbd9194487b5f15a5fb67a</id>
    </parent>
  </parents>
  <author>
    <name>Paul Davis</name>
    <email>davisp@puny.(none)</email>
  </author>
  <url>http://github.com/davisp/python-spidermonkey/commit/0d2d6d1435f0a5f1f1faf03be70f78eb32359d00</url>
  <id>0d2d6d1435f0a5f1f1faf03be70f78eb32359d00</id>
  <committed-date>2009-05-09T18:17:12-07:00</committed-date>
  <authored-date>2009-05-09T09:44:45-07:00</authored-date>
  <message>Initial JS iteration of Python objects.

This passes the basic tests. I need to add a check to detect if we're doing 'for
v in obj' vs 'for each (v in obj)' iteration as they behave differently in
JavaScript.</message>
  <tree>6633b5761584f3b716b75a3b6e1994ac9e2256d2</tree>
  <committer>
    <name>Paul Davis</name>
    <email>davisp@davis-2318.local</email>
  </committer>
</commit>
