Mercurial > pymonkey
changeset 136:b4e216d06e83
Added pymonkey.Script, which wraps a JSScript object, and context.compile_script()/execute_script().
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Sun, 23 Aug 2009 21:49:44 -0700 |
parents | 9157e7c9cb81 |
children | f83a1603c417 |
files | setup.py src/context.cpp src/object.cpp src/pymonkey.cpp src/script.cpp src/script.h tests/test_pymonkey.py |
diffstat | 7 files changed, 261 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/setup.py Sun Aug 23 21:04:51 2009 -0700 +++ b/setup.py Sun Aug 23 21:49:44 2009 -0700 @@ -41,6 +41,7 @@ 'utils.cpp', 'object.cpp', 'function.cpp', + 'script.cpp', 'undefined.cpp', 'context.cpp', 'runtime.cpp']
--- a/src/context.cpp Sun Aug 23 21:04:51 2009 -0700 +++ b/src/context.cpp Sun Aug 23 21:49:44 2009 -0700 @@ -37,6 +37,7 @@ #include "context.h" #include "object.h" #include "function.h" +#include "script.h" #include "utils.h" // This is the default JSOperationCallback for pymonkey-owned JS contexts, @@ -311,6 +312,65 @@ } static PyObject * +PYM_compileScript(PYM_JSContextObject *self, PyObject *args) +{ + PYM_SANITY_CHECK(self->runtime); + PYM_JSObject *object; + char *source = NULL; + int sourceLen; + const char *filename; + int lineNo; + + if (!PyArg_ParseTuple(args, "O!es#si", &PYM_JSObjectType, &object, + "utf-16", &source, &sourceLen, &filename, &lineNo)) + return NULL; + + PYM_UTF16String str(source, sourceLen); + + PYM_ENSURE_RUNTIME_MATCH(self->runtime, object->runtime); + + JSScript *script; + script = JS_CompileUCScript(self->cx, object->obj, str.jsbuffer, + str.jslen, filename, lineNo); + + if (script == NULL) { + PYM_jsExceptionToPython(self); + return NULL; + } + + return (PyObject *) PYM_newJSScript(self, script); +} + +static PyObject * +PYM_executeScript(PYM_JSContextObject *self, PyObject *args) +{ + PYM_SANITY_CHECK(self->runtime); + PYM_JSObject *object; + PYM_JSScript *script; + + if (!PyArg_ParseTuple(args, "O!O!", &PYM_JSObjectType, &object, + &PYM_JSScriptType, &script)) + return NULL; + + PYM_ENSURE_RUNTIME_MATCH(self->runtime, object->runtime); + PYM_ENSURE_RUNTIME_MATCH(self->runtime, script->base.runtime); + + jsval rval; + JSBool result; + Py_BEGIN_ALLOW_THREADS; + result = JS_ExecuteScript(self->cx, object->obj, script->script, &rval); + Py_END_ALLOW_THREADS; + + if (!result) { + PYM_jsExceptionToPython(self); + return NULL; + } + + PyObject *pyRval = PYM_jsvalToPyObject(self, rval); + return pyRval; +} + +static PyObject * PYM_evaluateScript(PYM_JSContextObject *self, PyObject *args) { PYM_SANITY_CHECK(self->runtime); @@ -485,6 +545,14 @@ {"init_standard_classes", (PyCFunction) PYM_initStandardClasses, METH_VARARGS, "Add standard classes and functions to the given object."}, + {"compile_script", + (PyCFunction) PYM_compileScript, METH_VARARGS, + "Compile the given JavaScript code using the given filename" + "and line number information."}, + {"execute_script", + (PyCFunction) PYM_executeScript, METH_VARARGS, + "Execute the given JavaScript script object in the context of " + "the given global object."}, {"evaluate_script", (PyCFunction) PYM_evaluateScript, METH_VARARGS, "Evaluate the given JavaScript code in the context of the given "
--- a/src/object.cpp Sun Aug 23 21:04:51 2009 -0700 +++ b/src/object.cpp Sun Aug 23 21:49:44 2009 -0700 @@ -245,6 +245,5 @@ JS_AddNamedRootRT(object->runtime->rt, &object->obj, "Pymonkey-Generated Object"); - return object; }
--- a/src/pymonkey.cpp Sun Aug 23 21:04:51 2009 -0700 +++ b/src/pymonkey.cpp Sun Aug 23 21:49:44 2009 -0700 @@ -39,6 +39,7 @@ #include "context.h" #include "object.h" #include "function.h" +#include "script.h" #include "utils.h" static PyMethodDef PYM_methods[] = { @@ -91,4 +92,11 @@ Py_INCREF(&PYM_JSFunctionType); PyModule_AddObject(module, "Function", (PyObject *) &PYM_JSFunctionType); + + PYM_JSScriptType.tp_base = &PYM_JSObjectType; + if (!PyType_Ready(&PYM_JSScriptType) < 0) + return; + + Py_INCREF(&PYM_JSScriptType); + PyModule_AddObject(module, "Script", (PyObject *) &PYM_JSScriptType); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/script.cpp Sun Aug 23 21:49:44 2009 -0700 @@ -0,0 +1,119 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Pymonkey. + * + * The Initial Developer of the Original Code is Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Atul Varma <atul@mozilla.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "script.h" +#include "utils.h" + +static void +PYM_JSScriptDealloc(PYM_JSScript *self) +{ + self->script = NULL; + PYM_JSObjectType.tp_dealloc((PyObject *) self); +} + +PyTypeObject PYM_JSScriptType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "pymonkey.Script", /*tp_name*/ + sizeof(PYM_JSScript), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /*tp_dealloc*/ + (destructor) PYM_JSScriptDealloc, + 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*/ + /*tp_flags*/ + Py_TPFLAGS_DEFAULT, + /* tp_doc */ + "JavaScript Script.", + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* 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 */ +}; + +PYM_JSScript * +PYM_newJSScript(PYM_JSContextObject *context, JSScript *script) +{ + JSObject *scriptObj = JS_GetScriptObject(script); + PYM_JSScript *object = NULL; + + if (scriptObj) + object = (PYM_JSScript *) PYM_findJSObject(context, scriptObj); + else { + scriptObj = JS_NewScriptObject(context->cx, script); + + if (scriptObj == NULL) { + PyErr_SetString(PYM_error, "JS_NewScriptObject() failed"); + return NULL; + } + } + + if (object == NULL) { + object = PyObject_New(PYM_JSScript, &PYM_JSScriptType); + if (object == NULL) + return NULL; + + object->script = script; + return (PYM_JSScript *) PYM_newJSObject(context, scriptObj, + (PYM_JSObject *) object); + } + return object; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/script.h Sun Aug 23 21:49:44 2009 -0700 @@ -0,0 +1,56 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Pymonkey. + * + * The Initial Developer of the Original Code is Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Atul Varma <atul@mozilla.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef PYM_SCRIPT_H +#define PYM_SCRIPT_H + +#include "object.h" +#include "context.h" + +#include <jsapi.h> +#include <Python.h> + +typedef struct { + PYM_JSObject base; + JSScript *script; +} PYM_JSScript; + +extern PyTypeObject PYM_JSScriptType; + +extern PYM_JSScript * +PYM_newJSScript(PYM_JSContextObject *context, JSScript *script); + +#endif
--- a/tests/test_pymonkey.py Sun Aug 23 21:04:51 2009 -0700 +++ b/tests/test_pymonkey.py Sun Aug 23 21:49:44 2009 -0700 @@ -32,6 +32,15 @@ was_raised = True self.assertTrue(was_raised) + def testCompileScriptWorks(self): + rt = pymonkey.Runtime() + cx = rt.new_context() + obj = cx.new_object() + cx.init_standard_classes(obj) + code = '5 + 1' + script = cx.compile_script(obj, code, '<string>', 1) + self.assertEqual(cx.execute_script(obj, script), 6) + def testErrorsRaisedIncludeStrings(self): self.assertRaises(pymonkey.error, self._evaljs, 'boop()') self.assertEqual(self.last_exception.args[1],