# HG changeset patch # User Atul Varma # Date 1246235337 25200 # Node ID 551ba05fe6ad8967e43a58522ac2bb4c58128fba # Parent 29eaa1fceff140261e21e3b023648450b3219274 factored out Runtime, Context, and utils into separate files. diff -r 29eaa1fceff1 -r 551ba05fe6ad context.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/context.c Sun Jun 28 17:28:57 2009 -0700 @@ -0,0 +1,72 @@ +#include "context.h" + +static void +PYM_JSContextDealloc(PYM_JSContextObject *self) +{ + if (self->cx) { + JS_DestroyContext(self->cx); + self->cx = NULL; + } + + Py_DECREF(self->runtime); + self->runtime = NULL; + + self->ob_type->tp_free((PyObject *) self); +} + +static PyObject * +PYM_getRuntime(PYM_JSContextObject *self, PyObject *args) +{ + Py_INCREF(self->runtime); + return (PyObject *) self->runtime; +} + +static PyMethodDef PYM_JSContextMethods[] = { + {"get_runtime", (PyCFunction) PYM_getRuntime, METH_VARARGS, + "Get the JavaScript runtime associated with this context."}, + {NULL, NULL, 0, NULL} +}; + +PyTypeObject PYM_JSContextType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "pymonkey.Context", /*tp_name*/ + sizeof(PYM_JSRuntimeObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /*tp_dealloc*/ + (destructor) PYM_JSContextDealloc, + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + /* tp_doc */ + "JavaScript Context.", + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PYM_JSContextMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; diff -r 29eaa1fceff1 -r 551ba05fe6ad context.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/context.h Sun Jun 28 17:28:57 2009 -0700 @@ -0,0 +1,17 @@ +#ifndef PYM_CONTEXT_H +#define PYM_CONTEXT_H + +#include "runtime.h" + +#include +#include + +typedef struct { + PyObject_HEAD + PYM_JSRuntimeObject *runtime; + JSContext *cx; +} PYM_JSContextObject; + +extern PyTypeObject PYM_JSContextType; + +#endif diff -r 29eaa1fceff1 -r 551ba05fe6ad pavement.py --- a/pavement.py Sun Jun 28 17:10:40 2009 -0700 +++ b/pavement.py Sun Jun 28 17:28:57 2009 -0700 @@ -23,7 +23,10 @@ "-o", "pymonkey.so", "-dynamiclib", "pymonkey.c", - "undefined.c"] + "utils.c", + "undefined.c", + "context.c", + "runtime.c"] ) if result: diff -r 29eaa1fceff1 -r 551ba05fe6ad pymonkey.c --- a/pymonkey.c Sun Jun 28 17:10:40 2009 -0700 +++ b/pymonkey.c Sun Jun 28 17:28:57 2009 -0700 @@ -1,6 +1,9 @@ #include "undefined.h" +#include "runtime.h" +#include "context.h" +#include "utils.h" -#include "jsapi.h" +#include static JSClass PYM_jsGlobalClass = { "PymonkeyGlobal", JSCLASS_GLOBAL_FLAGS, @@ -9,234 +12,6 @@ JSCLASS_NO_OPTIONAL_MEMBERS }; -static PyObject *PYM_error; - -static PyObject * -PYM_jsvalToPyObject(jsval value) { - if (JSVAL_IS_INT(value)) - return PyInt_FromLong(JSVAL_TO_INT(value)); - - if (JSVAL_IS_DOUBLE(value)) { - jsdouble *doubleRef = JSVAL_TO_DOUBLE(value); - return PyFloat_FromDouble(*doubleRef); - } - - if (value == JSVAL_FALSE) - Py_RETURN_FALSE; - - if (value == JSVAL_TRUE) - Py_RETURN_TRUE; - - if (JSVAL_IS_NULL(value)) - Py_RETURN_NONE; - - if (JSVAL_IS_VOID(value)) - Py_RETURN_UNDEFINED; - - if (JSVAL_IS_STRING(value) && JS_CStringsAreUTF8()) { - // TODO: What to do if C strings aren't UTF-8? The jschar * - // type isn't actually UTF-16, it's just "UTF-16-ish", so - // there doesn't seem to be any other lossless way of - // transferring the string other than perhaps by transmitting - // its JSON representation. - - JSString *str = JSVAL_TO_STRING(value); - const char *bytes = JS_GetStringBytes(str); - const char *errors; - return PyUnicode_DecodeUTF8(bytes, strlen(bytes), errors); - } - - // TODO: Support more types. - PyErr_SetString(PyExc_NotImplementedError, - "Data type conversion not implemented."); -} - -typedef struct { - PyObject_HEAD - JSRuntime *rt; -} PYM_JSRuntimeObject; - -static PyObject * -PYM_JSRuntimeNew(PyTypeObject *type, PyObject *args, - PyObject *kwds) -{ - PYM_JSRuntimeObject *self; - - self = (PYM_JSRuntimeObject *) type->tp_alloc(type, 0); - if (self != NULL) { - self->rt = JS_NewRuntime(8L * 1024L * 1024L); - if (!self->rt) { - PyErr_SetString(PYM_error, "JS_NewRuntime() failed"); - type->tp_dealloc((PyObject *) self); - self = NULL; - } - } - - return (PyObject *) self; -} - -static void -PYM_JSRuntimeDealloc(PYM_JSRuntimeObject *self) -{ - if (self->rt) { - JS_DestroyRuntime(self->rt); - self->rt = NULL; - } - - self->ob_type->tp_free((PyObject *) self); -} - -extern PyTypeObject PYM_JSContextType; - -typedef struct { - PyObject_HEAD - PYM_JSRuntimeObject *runtime; - JSContext *cx; -} PYM_JSContextObject; - -static PyObject * -PYM_newContext(PYM_JSRuntimeObject *self, PyObject *args) -{ - PYM_JSContextObject *context = PyObject_New(PYM_JSContextObject, - &PYM_JSContextType); - - context->runtime = self; - Py_INCREF(self); - - context->cx = JS_NewContext(self->rt, 8192); - if (context->cx == NULL) { - PyErr_SetString(PYM_error, "JS_NewContext() failed"); - Py_DECREF(context); - return NULL; - } - - JS_SetOptions(context->cx, JSOPTION_VAROBJFIX); - JS_SetVersion(context->cx, JSVERSION_LATEST); - - return (PyObject *) context; -} - -static PyMethodDef PYM_JSRuntimeMethods[] = { - {"new_context", (PyCFunction) PYM_newContext, METH_VARARGS, - "Create a new JavaScript context."}, - {NULL, NULL, 0, NULL} -}; - -static PyTypeObject PYM_JSRuntimeType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "pymonkey.Runtime", /*tp_name*/ - sizeof(PYM_JSRuntimeObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /*tp_dealloc*/ - (destructor) PYM_JSRuntimeDealloc, - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - /* tp_doc */ - "JavaScript Runtime.", - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - PYM_JSRuntimeMethods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PYM_JSRuntimeNew, /* tp_new */ -}; - -static void -PYM_JSContextDealloc(PYM_JSContextObject *self) -{ - if (self->cx) { - JS_DestroyContext(self->cx); - self->cx = NULL; - } - - Py_DECREF(self->runtime); - self->runtime = NULL; - - self->ob_type->tp_free((PyObject *) self); -} - -static PyObject * -PYM_getRuntime(PYM_JSContextObject *self, PyObject *args) -{ - Py_INCREF(self->runtime); - return (PyObject *) self->runtime; -} - -static PyMethodDef PYM_JSContextMethods[] = { - {"get_runtime", (PyCFunction) PYM_getRuntime, METH_VARARGS, - "Get the JavaScript runtime associated with this context."}, - {NULL, NULL, 0, NULL} -}; - -PyTypeObject PYM_JSContextType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "pymonkey.Context", /*tp_name*/ - sizeof(PYM_JSRuntimeObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /*tp_dealloc*/ - (destructor) PYM_JSContextDealloc, - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - /* tp_doc */ - "JavaScript Context.", - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - PYM_JSContextMethods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; - static PyObject * PYM_evaluate(PyObject *self, PyObject *args) { diff -r 29eaa1fceff1 -r 551ba05fe6ad runtime.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runtime.c Sun Jun 28 17:28:57 2009 -0700 @@ -0,0 +1,105 @@ +#include "runtime.h" +#include "context.h" +#include "utils.h" + +static PyObject * +PYM_JSRuntimeNew(PyTypeObject *type, PyObject *args, + PyObject *kwds) +{ + PYM_JSRuntimeObject *self; + + self = (PYM_JSRuntimeObject *) type->tp_alloc(type, 0); + if (self != NULL) { + self->rt = JS_NewRuntime(8L * 1024L * 1024L); + if (!self->rt) { + PyErr_SetString(PYM_error, "JS_NewRuntime() failed"); + type->tp_dealloc((PyObject *) self); + self = NULL; + } + } + + return (PyObject *) self; +} + +static void +PYM_JSRuntimeDealloc(PYM_JSRuntimeObject *self) +{ + if (self->rt) { + JS_DestroyRuntime(self->rt); + self->rt = NULL; + } + + self->ob_type->tp_free((PyObject *) self); +} + +static PyObject * +PYM_newContext(PYM_JSRuntimeObject *self, PyObject *args) +{ + PYM_JSContextObject *context = PyObject_New(PYM_JSContextObject, + &PYM_JSContextType); + + context->runtime = self; + Py_INCREF(self); + + context->cx = JS_NewContext(self->rt, 8192); + if (context->cx == NULL) { + PyErr_SetString(PYM_error, "JS_NewContext() failed"); + Py_DECREF(context); + return NULL; + } + + JS_SetOptions(context->cx, JSOPTION_VAROBJFIX); + JS_SetVersion(context->cx, JSVERSION_LATEST); + + return (PyObject *) context; +} + +static PyMethodDef PYM_JSRuntimeMethods[] = { + {"new_context", (PyCFunction) PYM_newContext, METH_VARARGS, + "Create a new JavaScript context."}, + {NULL, NULL, 0, NULL} +}; + +PyTypeObject PYM_JSRuntimeType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "pymonkey.Runtime", /*tp_name*/ + sizeof(PYM_JSRuntimeObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /*tp_dealloc*/ + (destructor) PYM_JSRuntimeDealloc, + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + /* tp_doc */ + "JavaScript Runtime.", + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PYM_JSRuntimeMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PYM_JSRuntimeNew, /* tp_new */ +}; diff -r 29eaa1fceff1 -r 551ba05fe6ad runtime.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runtime.h Sun Jun 28 17:28:57 2009 -0700 @@ -0,0 +1,14 @@ +#ifndef PYM_RUNTIME_H +#define PYM_RUNTIME_H + +#include +#include + +typedef struct { + PyObject_HEAD + JSRuntime *rt; +} PYM_JSRuntimeObject; + +extern PyTypeObject PYM_JSRuntimeType; + +#endif diff -r 29eaa1fceff1 -r 551ba05fe6ad undefined.h --- a/undefined.h Sun Jun 28 17:10:40 2009 -0700 +++ b/undefined.h Sun Jun 28 17:28:57 2009 -0700 @@ -1,3 +1,6 @@ +#ifndef PYM_UNDEFINED_H +#define PYM_UNDEFINED_H + #include #define Py_RETURN_UNDEFINED { Py_INCREF(PYM_undefined); \ @@ -10,3 +13,5 @@ extern PyTypeObject PYM_undefinedType; extern PyObject *PYM_undefined; + +#endif diff -r 29eaa1fceff1 -r 551ba05fe6ad utils.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utils.c Sun Jun 28 17:28:57 2009 -0700 @@ -0,0 +1,44 @@ +#include "utils.h" +#include "undefined.h" + +PyObject *PYM_error; + +PyObject * +PYM_jsvalToPyObject(jsval value) { + if (JSVAL_IS_INT(value)) + return PyInt_FromLong(JSVAL_TO_INT(value)); + + if (JSVAL_IS_DOUBLE(value)) { + jsdouble *doubleRef = JSVAL_TO_DOUBLE(value); + return PyFloat_FromDouble(*doubleRef); + } + + if (value == JSVAL_FALSE) + Py_RETURN_FALSE; + + if (value == JSVAL_TRUE) + Py_RETURN_TRUE; + + if (JSVAL_IS_NULL(value)) + Py_RETURN_NONE; + + if (JSVAL_IS_VOID(value)) + Py_RETURN_UNDEFINED; + + if (JSVAL_IS_STRING(value) && JS_CStringsAreUTF8()) { + // TODO: What to do if C strings aren't UTF-8? The jschar * + // type isn't actually UTF-16, it's just "UTF-16-ish", so + // there doesn't seem to be any other lossless way of + // transferring the string other than perhaps by transmitting + // its JSON representation. + + JSString *str = JSVAL_TO_STRING(value); + const char *bytes = JS_GetStringBytes(str); + const char *errors; + return PyUnicode_DecodeUTF8(bytes, strlen(bytes), errors); + } + + // TODO: Support more types. + PyErr_SetString(PyExc_NotImplementedError, + "Data type conversion not implemented."); +} diff -r 29eaa1fceff1 -r 551ba05fe6ad utils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utils.h Sun Jun 28 17:28:57 2009 -0700 @@ -0,0 +1,12 @@ +#ifndef PYM_UTILS_H +#define PYM_UTILS_H + +#include +#include + +extern PyObject *PYM_error; + +extern PyObject * +PYM_jsvalToPyObject(jsval value); + +#endif