Commits

Anonymous committed 3433175

C++ fu has atrophied.

  • Participants
  • Parent commits 50d8cf3

Comments (0)

Files changed (20)

spidermonkey/common/array.cpp

-#include <spidermonkey.h>
-
-PyObject*
-js2py_array(Context* cx, jsval val)
-{
-    return make_object(ArrayType, cx, val);
-}

spidermonkey/common/common.h

-/*
- * Copyright 2009 Paul J. Davis <paul.joseph.davis@gmail.com>
- *
- * This file is part of the python-spidermonkey package released
- * under the MIT license.
- *
- */
-
-#ifndef PYSM_COMMON_H
-#define PYSM_COMMON_H
-
-#include "python/python.h"
-
-jsval py2js(Context* cx, PyObject* obj);
-PyObject* js2py(Context* cx, jsval val);
-PyObject* js2py_with_parent(Context* cx, jsval val, jsval parent);
-
-jsval py2js_double(Context* cx, PyObject* obj);
-PyObject* js2py_double(Context* cx, jsval val);
-
-jsval py2js_integer(Context* cx, PyObject* obj);
-jsval long2js_integer(Context* cx, long val);
-PyObject* js2py_integer(Context* cx, jsval val);
-
-JSString* py2js_string_obj(Context* cx, PyObject* str);
-jsval py2js_string(Context* cx, PyObject* str);
-PyObject* js2py_string(Context* cx, jsval val);
-
-jsval py2js_object(Context* cx, PyObject* pyobj);
-PyObject* js2py_object(Context* cx, jsval val);
-
-PyObject* js2py_array(Context* cx, jsval val);
-
-PyObject* js2py_function(Context* cx, jsval val, jsval parent);
-
-#endif

spidermonkey/common/convert.cpp

-/*
- * Copyright 2009 Paul J. Davis <paul.joseph.davis@gmail.com>
- *
- * This file is part of the python-spidermonkey package released
- * under the MIT license.
- *
- */
-
-#include <spidermonkey.h>
-
-jsval
-py2js(Context* cx, PyObject* obj)
-{
-    if(obj == Py_None)
-    {
-        return JSVAL_NULL;
-    }
-    else if(obj == Py_True)
-    {
-        return JSVAL_TRUE;
-    }
-    else if(obj == Py_False)
-    {
-        return JSVAL_FALSE;
-    }
-    else if(PyInt_Check(obj) || PyLong_Check(obj))
-    {
-        return py2js_integer(cx, obj);
-    }
-    else if(PyFloat_Check(obj))
-    {
-        return py2js_double(cx, obj);
-    }
-    else if(PyString_Check(obj) || PyUnicode_Check(obj))
-    {
-        return py2js_string(cx, obj);
-    }
-    else if(PyObject_TypeCheck(obj, ObjectType))
-    {
-        return ((Object*) obj)->val;
-    }
-    else
-    {
-        return py2js_object(cx, obj);
-    }
-
-    PyErr_SetString(PyExc_ValueError, "Unable to convert Python value to JS.");
-    return JSVAL_VOID;
-}
-
-PyObject*
-js2py(Context* cx, jsval val)
-{
-    return js2py_with_parent(cx, val, JSVAL_NULL);
-}
-
-PyObject*
-js2py_with_parent(Context* cx, jsval val, jsval parent)
-{
-    JSType vtype = JS_TypeOfValue(cx->cx, val);
-
-    /*
-        There's not JSType for null. Or rather, its
-        reported as Object which causes segfaults.
-    */
-    if(val == JSVAL_NULL || val == JSVAL_VOID)
-    {
-        Py_RETURN_NONE;
-    }
-    else if(vtype == JSTYPE_BOOLEAN)
-    {
-        if(val == JSVAL_TRUE)
-        {
-            Py_RETURN_TRUE;
-        }
-        else
-        {
-            Py_RETURN_FALSE;
-        }
-    }
-    else if(vtype == JSTYPE_STRING)
-    {
-        return js2py_string(cx, val);
-    }
-    else if(vtype == JSTYPE_NUMBER)
-    {
-        if(JSVAL_IS_INT(val)) return js2py_integer(cx, val);
-        else return js2py_double(cx, val);
-    }
-    else if(vtype == JSTYPE_FUNCTION)
-    {
-        return js2py_function(cx, val, parent);
-    }
-    else if(vtype == JSTYPE_OBJECT)
-    {
-        JSObject* obj = JSVAL_TO_OBJECT(val);
-        if(JS_IsArrayObject(cx->cx, obj))
-        {
-            return js2py_array(cx, val);
-        }
-        
-        return js2py_object(cx, val);
-    }
-    
-    PyErr_SetString(PyExc_RuntimeError, "Unknown JSVAL type.");
-    return NULL;
-}

spidermonkey/common/double.cpp

-/*
- * Copyright 2009 Paul J. Davis <paul.joseph.davis@gmail.com>
- *
- * This file is part of the python-spidermonkey package released
- * under the MIT license.
- *
- */
-
-#include <spidermonkey.h>
-
-jsval
-py2js_double(Context* cx, PyObject* obj)
-{
-    jsval rval = JSVAL_VOID;
-    double pyval = PyFloat_AsDouble(obj);
-    if(PyErr_Occurred()) goto error;
-
-    if(!JS_NewNumberValue(cx->cx, pyval, &rval))
-    {
-        PyErr_SetString(PyExc_ValueError, "Failed to convert number.");
-        goto error;
-    }
-
-    goto success;
-
-error:
-success:
-    return rval;
-}
-
-PyObject*
-js2py_double(Context* cx, jsval val)
-{
-    double rval;
-
-    if(!JS_ValueToNumber(cx->cx, val, &rval))
-    {
-        PyErr_SetString(PyExc_TypeError, "Invalid JS number value.");
-        return NULL;
-    }
-
-    return PyFloat_FromDouble(rval);
-}

spidermonkey/common/function.cpp

-
-#include <spidermonkey.h>
-
-PyObject*
-js2py_function(Context* cx, jsval val, jsval parent)
-{
-    Function* ret = NULL;
-
-    if(parent == JSVAL_VOID || !JSVAL_IS_OBJECT(parent))
-    {
-        PyErr_BadInternalCall();
-        goto error;
-    }
-    
-    ret = (Function*) make_object(FunctionType, cx, val);
-    if(ret == NULL) goto error;
-
-    ret->parent = parent;
-    if(!JS_AddRoot(cx->cx, &(ret->parent)))
-    {
-        PyErr_SetString(PyExc_RuntimeError, "Failed to add GC root.");
-        goto error;
-    }
-
-    goto success;
-
-error:
-    Py_XDECREF((PyObject*)ret);
-    ret = NULL; // In case of AddRoot error.
-success:
-    return (PyObject*) ret;
-}

spidermonkey/common/integer.cpp

-/*
- * Copyright 2009 Paul J. Davis <paul.joseph.davis@gmail.com>
- *
- * This file is part of the python-spidermonkey package released
- * under the MIT license.
- *
- */
-
-#include <spidermonkey.h>
-
-jsval
-py2js_integer(Context* cx, PyObject* obj)
-{
-    long pyval;
-    
-    if(PyInt_Check(obj))
-    {
-        pyval = PyInt_AsLong(obj);
-        if(PyErr_Occurred()) return JSVAL_VOID;
-    }
-    else
-    {
-        pyval = PyLong_AsLong(obj);
-        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 done;
-    }
-    
-    if(!JS_NewNumberValue(cx->cx, pyval, &ret))
-    {
-        PyErr_SetString(PyExc_ValueError, "Failed to convert number.");
-        goto done;
-    }
-
-done:
-    return ret;
-}
-
-PyObject*
-js2py_integer(Context* cx, jsval val)
-{
-    int32 rval;
-
-    if(!JS_ValueToInt32(cx->cx, val, &rval))
-    {
-        PyErr_SetString(PyExc_TypeError, "Invalid JS integer value.");
-        return NULL;
-    }
-
-    return PyInt_FromLong(rval);
-}

spidermonkey/common/object.cpp

-
-#include <spidermonkey.h>
-
-jsval
-py2js_object(Context* cx, PyObject* pyobj)
-{
-    PyObject* hashable = NULL;
-    PyObject* attached = NULL;
-    JSClass* klass = NULL;
-    JSObject* jsobj = NULL;
-    jsval pyval;
-    jsval ret = JSVAL_VOID;
-   
-    klass = create_class(cx, pyobj);
-    if(klass == NULL) goto error;
-
-    jsobj = JS_NewObject(cx->cx, klass, NULL, NULL);
-    if(jsobj == NULL)
-    {
-        PyErr_SetString(PyExc_RuntimeError, "Failed to create JS object.");
-        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);
-    pyval = PRIVATE_TO_JSVAL(attached);
-    if(!JS_SetReservedSlot(cx->cx, jsobj, 0, pyval))
-    {
-        PyErr_SetString(PyExc_RuntimeError, "Failed to store ref'ed object.");
-        goto error;
-    }
-
-    hashable = HashCObj_FromVoidPtr(attached);
-    if(hashable == NULL)
-    {
-        PyErr_SetString(PyExc_RuntimeError, "Failed to make hashable pointer.");
-        goto error;
-    }
-
-    if(Context_add_object(cx, hashable) < 0)
-    {
-        PyErr_SetString(PyExc_RuntimeError, "Failed to store reference.");
-        goto error;
-    }
-
-    ret = OBJECT_TO_JSVAL(jsobj);
-    goto success;
-
-error:
-    Py_XDECREF(attached);
-success:
-    return ret;
-}
-
-PyObject*
-js2py_object(Context* cx, jsval val)
-{
-    return make_object(ObjectType, cx, val);
-}

spidermonkey/common/string.cpp

-/*
- * Copyright 2009 Paul J. Davis <paul.joseph.davis@gmail.com>
- *
- * This file is part of the python-spidermonkey package released
- * under the MIT license.
- *
- */
-
-#include <spidermonkey.h>
-
-JSString*
-py2js_string_obj(Context* cx, PyObject* str)
-{
-    PyObject* conv = NULL;
-    PyObject* encoded = NULL;
-    JSString* ret = NULL;
-    char* bytes;
-    Py_ssize_t len;
-
-    if(PyString_Check(str))
-    {
-        conv = PyUnicode_FromEncodedObject(str, "utf-8", "replace");
-        if(conv == NULL) goto error;
-        str = conv;
-    }
-    else if(!PyUnicode_Check(str))
-    {
-        PyErr_SetString(PyExc_TypeError, "Invalid string conversion.");
-        goto error;
-    }
-
-    encoded = PyUnicode_AsEncodedString(str, "utf-16", "strict");
-    if(encoded == NULL) goto error;
-    if(PyString_AsStringAndSize(encoded, &bytes, &len) < 0) goto error;
-    if(len < 2)
-    {
-        PyErr_SetString(PyExc_ValueError, "Failed to find byte-order mark.");
-        goto error;
-    }
-
-    if(((unsigned short*) bytes)[0] != 0xFEFF)
-    {
-        PyErr_SetString(PyExc_ValueError, "Invalid UTF-16 BOM");
-        goto error;
-    }
-
-    ret = JS_NewUCStringCopyN(cx->cx, (jschar*) (bytes+2), (len/2)-1);
-    
-    goto success;
-
-error:
-success:
-    Py_XDECREF(conv);
-    Py_XDECREF(encoded);
-    return ret;
-}
-
-jsval
-py2js_string(Context* cx, PyObject* str)
-{
-    JSString* val = py2js_string_obj(cx, str);
-    if(val == NULL)
-    {
-        PyErr_Clear();
-        return JSVAL_VOID;
-    }
-
-    return STRING_TO_JSVAL(val);
-}
-
-PyObject*
-js2py_string(Context* cx, jsval val)
-{
-    JSString* str;
-    jschar* bytes;
-    size_t len;
-
-    if(!JSVAL_IS_STRING(val))
-    {
-        PyErr_SetString(PyExc_TypeError, "Value is not a JS String.");
-        return NULL;
-    }
-
-    str = JSVAL_TO_STRING(val);
-    len = JS_GetStringLength(str);
-    bytes = JS_GetStringChars(str);
-
-    return PyUnicode_Decode((const char*) bytes, len*2, "utf-16", "strict");
-}

spidermonkey/convert/array.cpp

+#include <spidermonkey.h>
+
+PyObject*
+js2py_array(Context* cx, jsval val)
+{
+    return make_object(ArrayType, cx, val);
+}

spidermonkey/convert/convert.cpp

+/*
+ * Copyright 2009 Paul J. Davis <paul.joseph.davis@gmail.com>
+ *
+ * This file is part of the python-spidermonkey package released
+ * under the MIT license.
+ *
+ */
+
+#include <spidermonkey.h>
+
+jsval
+py2js(Context* cx, PyObject* obj)
+{
+    if(obj == Py_None)
+    {
+        return JSVAL_NULL;
+    }
+    else if(obj == Py_True)
+    {
+        return JSVAL_TRUE;
+    }
+    else if(obj == Py_False)
+    {
+        return JSVAL_FALSE;
+    }
+    else if(PyInt_Check(obj) || PyLong_Check(obj))
+    {
+        return py2js_integer(cx, obj);
+    }
+    else if(PyFloat_Check(obj))
+    {
+        return py2js_double(cx, obj);
+    }
+    else if(PyString_Check(obj) || PyUnicode_Check(obj))
+    {
+        return py2js_string(cx, obj);
+    }
+    else if(PyObject_TypeCheck(obj, ObjectType))
+    {
+        return ((Object*) obj)->val;
+    }
+    else
+    {
+        return py2js_object(cx, obj);
+    }
+
+    PyErr_SetString(PyExc_ValueError, "Unable to convert Python value to JS.");
+    return JSVAL_VOID;
+}
+
+PyObject*
+js2py(Context* cx, jsval val)
+{
+    return js2py_with_parent(cx, val, JSVAL_NULL);
+}
+
+PyObject*
+js2py_with_parent(Context* cx, jsval val, jsval parent)
+{
+    JSType vtype = JS_TypeOfValue(cx->cx, val);
+
+    /*
+        There's not JSType for null. Or rather, its
+        reported as Object which causes segfaults.
+    */
+    if(val == JSVAL_NULL || val == JSVAL_VOID)
+    {
+        Py_RETURN_NONE;
+    }
+    else if(vtype == JSTYPE_BOOLEAN)
+    {
+        if(val == JSVAL_TRUE)
+        {
+            Py_RETURN_TRUE;
+        }
+        else
+        {
+            Py_RETURN_FALSE;
+        }
+    }
+    else if(vtype == JSTYPE_STRING)
+    {
+        return js2py_string(cx, val);
+    }
+    else if(vtype == JSTYPE_NUMBER)
+    {
+        if(JSVAL_IS_INT(val)) return js2py_integer(cx, val);
+        else return js2py_double(cx, val);
+    }
+    else if(vtype == JSTYPE_FUNCTION)
+    {
+        return js2py_function(cx, val, parent);
+    }
+    else if(vtype == JSTYPE_OBJECT)
+    {
+        JSObject* obj = JSVAL_TO_OBJECT(val);
+        if(JS_IsArrayObject(cx->cx, obj))
+        {
+            return js2py_array(cx, val);
+        }
+        
+        return js2py_object(cx, val);
+    }
+    
+    PyErr_SetString(PyExc_RuntimeError, "Unknown JSVAL type.");
+    return NULL;
+}

spidermonkey/convert/convert.h

+/*
+ * Copyright 2009 Paul J. Davis <paul.joseph.davis@gmail.com>
+ *
+ * This file is part of the python-spidermonkey package released
+ * under the MIT license.
+ *
+ */
+
+#ifndef PYSM_CONVERT_H
+#define PYSM_CONVERT_H
+
+#include "python/python.h"
+
+jsval py2js(Context* cx, PyObject* obj);
+PyObject* js2py(Context* cx, jsval val);
+PyObject* js2py_with_parent(Context* cx, jsval val, jsval parent);
+
+jsval py2js_double(Context* cx, PyObject* obj);
+PyObject* js2py_double(Context* cx, jsval val);
+
+jsval py2js_integer(Context* cx, PyObject* obj);
+jsval long2js_integer(Context* cx, long val);
+PyObject* js2py_integer(Context* cx, jsval val);
+
+JSString* py2js_string_obj(Context* cx, PyObject* str);
+jsval py2js_string(Context* cx, PyObject* str);
+PyObject* js2py_string(Context* cx, jsval val);
+
+jsval py2js_object(Context* cx, PyObject* pyobj);
+PyObject* js2py_object(Context* cx, jsval val);
+
+PyObject* js2py_array(Context* cx, jsval val);
+
+PyObject* js2py_function(Context* cx, jsval val, jsval parent);
+
+#endif

spidermonkey/convert/double.cpp

+/*
+ * Copyright 2009 Paul J. Davis <paul.joseph.davis@gmail.com>
+ *
+ * This file is part of the python-spidermonkey package released
+ * under the MIT license.
+ *
+ */
+
+#include <spidermonkey.h>
+
+jsval
+py2js_double(Context* cx, PyObject* obj)
+{
+    jsval rval = JSVAL_VOID;
+    double pyval = PyFloat_AsDouble(obj);
+    if(PyErr_Occurred()) goto error;
+
+    if(!JS_NewNumberValue(cx->cx, pyval, &rval))
+    {
+        PyErr_SetString(PyExc_ValueError, "Failed to convert number.");
+        goto error;
+    }
+
+    goto success;
+
+error:
+success:
+    return rval;
+}
+
+PyObject*
+js2py_double(Context* cx, jsval val)
+{
+    double rval;
+
+    if(!JS_ValueToNumber(cx->cx, val, &rval))
+    {
+        PyErr_SetString(PyExc_TypeError, "Invalid JS number value.");
+        return NULL;
+    }
+
+    return PyFloat_FromDouble(rval);
+}

spidermonkey/convert/function.cpp

+
+#include <spidermonkey.h>
+
+PyObject*
+js2py_function(Context* cx, jsval val, jsval parent)
+{
+    Function* ret = NULL;
+
+    if(parent == JSVAL_VOID || !JSVAL_IS_OBJECT(parent))
+    {
+        PyErr_BadInternalCall();
+        goto error;
+    }
+    
+    ret = (Function*) make_object(FunctionType, cx, val);
+    if(ret == NULL) goto error;
+
+    ret->parent = parent;
+    if(!JS_AddRoot(cx->cx, &(ret->parent)))
+    {
+        PyErr_SetString(PyExc_RuntimeError, "Failed to add GC root.");
+        goto error;
+    }
+
+    goto success;
+
+error:
+    Py_XDECREF((PyObject*)ret);
+    ret = NULL; // In case of AddRoot error.
+success:
+    return (PyObject*) ret;
+}

spidermonkey/convert/integer.cpp

+/*
+ * Copyright 2009 Paul J. Davis <paul.joseph.davis@gmail.com>
+ *
+ * This file is part of the python-spidermonkey package released
+ * under the MIT license.
+ *
+ */
+
+#include <spidermonkey.h>
+
+jsval
+py2js_integer(Context* cx, PyObject* obj)
+{
+    long pyval;
+    
+    if(PyInt_Check(obj))
+    {
+        pyval = PyInt_AsLong(obj);
+        if(PyErr_Occurred()) return JSVAL_VOID;
+    }
+    else
+    {
+        pyval = PyLong_AsLong(obj);
+        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 done;
+    }
+    
+    if(!JS_NewNumberValue(cx->cx, pyval, &ret))
+    {
+        PyErr_SetString(PyExc_ValueError, "Failed to convert number.");
+        goto done;
+    }
+
+done:
+    return ret;
+}
+
+PyObject*
+js2py_integer(Context* cx, jsval val)
+{
+    int32 rval;
+
+    if(!JS_ValueToInt32(cx->cx, val, &rval))
+    {
+        PyErr_SetString(PyExc_TypeError, "Invalid JS integer value.");
+        return NULL;
+    }
+
+    return PyInt_FromLong(rval);
+}

spidermonkey/convert/object.cpp

+
+#include <spidermonkey.h>
+
+jsval
+py2js_object(Context* cx, PyObject* pyobj)
+{
+    PyObject* hashable = NULL;
+    PyObject* attached = NULL;
+    JSClass* klass = NULL;
+    JSObject* jsobj = NULL;
+    jsval pyval;
+    jsval ret = JSVAL_VOID;
+   
+    klass = create_class(cx, pyobj);
+    if(klass == NULL) goto error;
+
+    jsobj = JS_NewObject(cx->cx, klass, NULL, NULL);
+    if(jsobj == NULL)
+    {
+        PyErr_SetString(PyExc_RuntimeError, "Failed to create JS object.");
+        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);
+    pyval = PRIVATE_TO_JSVAL(attached);
+    if(!JS_SetReservedSlot(cx->cx, jsobj, 0, pyval))
+    {
+        PyErr_SetString(PyExc_RuntimeError, "Failed to store ref'ed object.");
+        goto error;
+    }
+
+    hashable = HashCObj_FromVoidPtr(attached);
+    if(hashable == NULL)
+    {
+        PyErr_SetString(PyExc_RuntimeError, "Failed to make hashable pointer.");
+        goto error;
+    }
+
+    if(Context_add_object(cx, hashable) < 0)
+    {
+        PyErr_SetString(PyExc_RuntimeError, "Failed to store reference.");
+        goto error;
+    }
+
+    ret = OBJECT_TO_JSVAL(jsobj);
+    goto success;
+
+error:
+    Py_XDECREF(attached);
+success:
+    return ret;
+}
+
+PyObject*
+js2py_object(Context* cx, jsval val)
+{
+    return make_object(ObjectType, cx, val);
+}

spidermonkey/convert/string.cpp

+/*
+ * Copyright 2009 Paul J. Davis <paul.joseph.davis@gmail.com>
+ *
+ * This file is part of the python-spidermonkey package released
+ * under the MIT license.
+ *
+ */
+
+#include <spidermonkey.h>
+
+JSString*
+py2js_string_obj(Context* cx, PyObject* str)
+{
+    PyObject* conv = NULL;
+    PyObject* encoded = NULL;
+    JSString* ret = NULL;
+    char* bytes;
+    Py_ssize_t len;
+
+    if(PyString_Check(str))
+    {
+        conv = PyUnicode_FromEncodedObject(str, "utf-8", "replace");
+        if(conv == NULL) goto error;
+        str = conv;
+    }
+    else if(!PyUnicode_Check(str))
+    {
+        PyErr_SetString(PyExc_TypeError, "Invalid string conversion.");
+        goto error;
+    }
+
+    encoded = PyUnicode_AsEncodedString(str, "utf-16", "strict");
+    if(encoded == NULL) goto error;
+    if(PyString_AsStringAndSize(encoded, &bytes, &len) < 0) goto error;
+    if(len < 2)
+    {
+        PyErr_SetString(PyExc_ValueError, "Failed to find byte-order mark.");
+        goto error;
+    }
+
+    if(((unsigned short*) bytes)[0] != 0xFEFF)
+    {
+        PyErr_SetString(PyExc_ValueError, "Invalid UTF-16 BOM");
+        goto error;
+    }
+
+    ret = JS_NewUCStringCopyN(cx->cx, (jschar*) (bytes+2), (len/2)-1);
+    
+    goto success;
+
+error:
+success:
+    Py_XDECREF(conv);
+    Py_XDECREF(encoded);
+    return ret;
+}
+
+jsval
+py2js_string(Context* cx, PyObject* str)
+{
+    JSString* val = py2js_string_obj(cx, str);
+    if(val == NULL)
+    {
+        PyErr_Clear();
+        return JSVAL_VOID;
+    }
+
+    return STRING_TO_JSVAL(val);
+}
+
+PyObject*
+js2py_string(Context* cx, jsval val)
+{
+    JSString* str;
+    jschar* bytes;
+    size_t len;
+
+    if(!JSVAL_IS_STRING(val))
+    {
+        PyErr_SetString(PyExc_TypeError, "Value is not a JS String.");
+        return NULL;
+    }
+
+    str = JSVAL_TO_STRING(val);
+    len = JS_GetStringLength(str);
+    bytes = JS_GetStringChars(str);
+
+    return PyUnicode_Decode((const char*) bytes, len*2, "utf-16", "strict");
+}

spidermonkey/javascript/javascript.h

 #ifndef PYSM_JAVASCRIPT_H
 #define PYSM_JAVASCRIPT_H
 
+#include <spidermonkey.h>
+
 extern JSClass js_global_class;
 
 JSClass* create_class(Context* cx, PyObject* pyobj);

spidermonkey/spidermonkey.h

 
 #include <jsapi.h>
 
-#include "common/common.h"
+#include "utils/utils.h"
+#include "convert/convert.h"
 #include "javascript/javascript.h"
 #include "python/python.h"
 

spidermonkey/utils/utils.cpp

+
+#include <spidermonkey.h>
+
+PyObjXDR::PyObjXDR(PyObject* p)
+{
+    this->data = p;
+}
+
+PyObjXDR::~PyObjXDR()
+{
+    Py_XDECREF(this->data);
+}
+
+PyObject*
+PyObjXDR::get()
+{
+    return this->data
+}

spidermonkey/utils/utils.h

+/*
+ * Copyright 2009 Paul J. Davis <paul.joseph.davis@gmail.com>
+ *
+ * This file is part of the python-spidermonkey package released
+ * under the MIT license.
+ *
+ */
+
+#ifndef PYSM_CONVERT_H
+#define PYSM_CONVERT_H
+
+#include <Python.h>
+
+class PyObjXDR {
+    public:
+        explicit PyObjXDR(PyObject* p = 0);
+        ~PyObjXDR();
+
+        void reset(PyObject* p = 0);
+    
+        PyObject* get() const;
+    
+    protected:
+        PyObjXDR() {}
+    
+    private:
+        PyObjXDR(const PyObjXDR&);
+        const PyObjXDR& operator=(const PyObjXDR&);
+        
+        PyObject*   data;
+};
+
+#endif