changeset 170:dd32a92f6b4f

Initial attempt at renaming pymonkey to pydermonkey.
author Atul Varma <varmaa@toolness.com>
date Tue, 01 Sep 2009 03:07:24 -0700
parents 2b98d4643c44
children 478c672348dc
files README docs/rendered/_sources/index.txt docs/rendered/_sources/pydermonkey.txt docs/rendered/_sources/pymonkey.txt docs/rendered/genindex.html docs/rendered/index.html docs/rendered/modindex.html docs/rendered/pydermonkey.html docs/rendered/pymonkey.html docs/rendered/search.html docs/rendered/searchindex.js docs/src/conf.py docs/src/index.txt docs/src/pydermonkey.txt docs/src/pymonkey.txt setup.py src/context.cpp src/context.h src/function.cpp src/function.h src/object.cpp src/object.h src/pydermonkey.cpp src/pymonkey.cpp src/runtime.cpp src/runtime.h src/script.cpp src/script.h src/undefined.cpp src/undefined.h src/utils.cpp src/utils.h tests/test_pydermonkey.py tests/test_pymonkey.py
diffstat 34 files changed, 2561 insertions(+), 2561 deletions(-) [+]
line wrap: on
line diff
--- a/README	Sun Aug 30 20:56:43 2009 -0700
+++ b/README	Tue Sep 01 03:07:24 2009 -0700
@@ -1,8 +1,8 @@
-Pymonkey README
+Pydermonkey README
 ---------------
 
-Pymonkey is a Python C extension module to expose the Mozilla
+Pydermonkey is a Python C extension module to expose the Mozilla
 SpiderMonkey engine to Python.
 
-Please run "python setup.py docs" to open the full Pymonkey
+Please run "python setup.py docs" to open the full Pydermonkey
 documentation in your web browser.
--- a/docs/rendered/_sources/index.txt	Sun Aug 30 20:56:43 2009 -0700
+++ b/docs/rendered/_sources/index.txt	Tue Sep 01 03:07:24 2009 -0700
@@ -1,20 +1,20 @@
-.. Pymonkey documentation master file, created by
+.. Pydermonkey documentation master file, created by
    sphinx-quickstart on Mon Jul  6 17:20:31 2009.
    You can adapt this file completely to your liking, but it should at least
    contain the root `toctree` directive.
 
 ======================
-Pymonkey Documentation
+Pydermonkey Documentation
 ======================
 
-Pymonkey is a Python C extension module to expose the `Mozilla
+Pydermonkey is a Python C extension module to expose the `Mozilla
 SpiderMonkey <https://developer.mozilla.org/en/SpiderMonkey>`_ engine
 to Python.
 
 .. toctree::
    :maxdepth: 2
 
-   pymonkey
+   pydermonkey
 
 Rationale and Goals:
 
@@ -34,17 +34,17 @@
   <https://wiki.mozilla.org/ServerJS>`_ are currently paving the way
   in this field. There's Java-based solutions like Rhino out there,
   but nothing really mature is available for the Python
-  world. Ideally, Pymonkey should enable a Python programmer to create
+  world. Ideally, Pydermonkey should enable a Python programmer to create
   a custom sandboxed environment for executing JS code without needing
   to write any C.
 
-* Pymonkey should have awesome Sphinx documentation with doctests and
+* Pydermonkey should have awesome Sphinx documentation with doctests and
   all the trappings of a model Python package. Not only should it be
   easy for Python programmers to learn how to use the module, but it
   should also be easy for them to learn more about how SpiderMonkey
   works by reading the documentation and playing around with the code.
 
-* Pymonkey needs to have outstanding developer ergonomics. Full
+* Pydermonkey needs to have outstanding developer ergonomics. Full
   cross-language stack tracebacks should be available, for instance,
   and developers should be able to easily debug. Access to memory
   profiling facilities in JS-land is a must.
@@ -69,7 +69,7 @@
 Building, Testing, and Installing
 =================================
 
-From the root of your pymonkey repository, run::
+From the root of your pydermonkey repository, run::
 
   python setup.py build test
 
@@ -86,7 +86,7 @@
 ==========
 
 There's a number of challenges that need to be resolved before
-pymonkey can be really usable. Here's some of them.
+pydermonkey can be really usable. Here's some of them.
 
 **Garbage Collection**
 
@@ -100,7 +100,7 @@
 <https://developer.mozilla.org/en/Interfacing_with_the_XPCOM_cycle_collector>`_.
 
 For the time being, however, such cycles can be manually broken via
-:meth:`pymonkey.Context.clear_object_private()` on valid objects and functions.
+:meth:`pydermonkey.Context.clear_object_private()` on valid objects and functions.
 
 Indices and Tables
 ==================
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/rendered/_sources/pydermonkey.txt	Tue Sep 01 03:07:24 2009 -0700
@@ -0,0 +1,446 @@
+:mod:`pydermonkey` --- Access SpiderMonkey from Python
+===================================================
+
+.. module:: pydermonkey
+   :synopsis: Access SpiderMonkey from Python
+
+.. testsetup:: *
+
+   import pydermonkey
+
+This module offers a low-level interface to the `Mozilla SpiderMonkey
+<https://developer.mozilla.org/en/SpiderMonkey>`_ JavaScript engine.
+
+.. exception:: error
+
+   This is the type of any SpiderMonkey-related errors thrown by this
+   module.
+
+   If the error is a wrapped JavaScript exception, the first argument
+   will be the thrown JS exception, and the second argument will be 
+   the JS exception converted to a string. Otherwise, the error
+   will only contain a descriptive string argument.
+
+   For example:
+
+     >>> cx = pydermonkey.Runtime().new_context()
+     >>> cx.evaluate_script(cx.new_object(), 'throw 1', '<string>', 1)
+     Traceback (most recent call last):
+     ...
+     error: (1, u'1')
+
+.. data:: undefined
+
+   This is the singleton that represents the JavaScript value
+   ``undefined``, as Python has no equivalent representation
+   (JavaScript's ``null`` is mapped to Python's ``None`` object).
+   For instance:
+
+     >>> cx = pydermonkey.Runtime().new_context()
+     >>> cx.evaluate_script(cx.new_object(), '', '<string>', 1)
+     pydermonkey.undefined
+
+   This object also has a "falsy" value:
+
+     >>> if not pydermonkey.undefined:
+     ...   print "See, it's falsy!"
+     See, it's falsy!
+
+.. class:: Object
+
+   This is the type of JavaScript objects. Such objects can only be
+   created via Pydermonkey calls like :meth:`Context.new_object()` or
+   through the execution of JS code, but this type object can be used
+   with Python's built-in :func:`isinstance()` to verify that an
+   object is a JS object, like so:
+
+     >>> obj = pydermonkey.Runtime().new_context().new_object()
+     >>> isinstance(obj, pydermonkey.Object)
+     True
+
+   Note that :class:`Object` and all its subclasses are
+   identity-preserving when passed between Python and
+   JavaScript code. For instance:
+
+     >>> cx = pydermonkey.Runtime().new_context()
+     >>> obj1 = cx.new_object()
+     >>> obj2 = cx.evaluate_script(obj1, 'this', '<string>', 1)
+     >>> obj1 is obj2
+     True
+
+   .. method:: get_runtime()
+
+      Returns the :class:`Runtime` that the object belongs to.
+
+.. class:: Function
+
+   This is the type of JavaScript functions, which is a subtype of
+   :class:`Object`.
+
+   .. data:: filename
+
+      Name of the file that contains the function's original JS source
+      code. If the function isn't a JS function, this value is
+      ``None``.
+
+   .. data:: base_lineno
+
+      The line number at which the function's JS source code begins.
+
+   .. data:: line_extent
+
+      The number of lines comprising the function's JS source code.
+
+   .. data:: is_python
+
+      Whether or not the function is actually implemented in Python.
+      If it is, you can use :meth:`Context.get_object_private()` to
+      retrieve this Python function.
+
+.. class:: Script
+
+   This is the type of compiled JavaScript scripts; it's actually a
+   subtype of :class:`Object`, though when exposed to JS code it
+   doesn't provide access to any special data or functionality.
+
+   Script instances have a read-only buffer interface that exposes
+   their bytecode. This can be accessed by passing an instance to
+   Python's built-in ``buffer()`` function.
+
+   .. data:: filename
+
+      The filename of the script's original source code.
+
+   .. data:: base_lineno
+
+      The line number at which the script's original source code
+      begins.
+
+   .. data:: line_extent
+
+      The number of lines comprising the original source code.
+
+.. class:: Context
+
+   This is the type of JavaScript context objects. Contexts can only
+   be created via a call to :meth:`Runtime.new_context()`, but this
+   type object can be used with Python's built-in :func:`isinstance()`
+   to verify that an object is a context, like so:
+
+     >>> cx = pydermonkey.Runtime().new_context()
+     >>> isinstance(cx, pydermonkey.Context)
+     True
+
+   JS contexts are weak-referencable.
+
+   .. method:: get_runtime()
+
+      Returns the :class:`Runtime` that the context belongs to.
+
+   .. method:: get_stack()
+
+      Returns a dictionary containing information about the context's
+      current stack.
+
+      The dictionary contains the following string keys:
+
+      +------------------------------+-------------------------------------+
+      | key                          | value                               |
+      +==============================+=====================================+
+      | :const:`script`              | :class:`Script` of the frame.       |
+      |                              | This may be ``None`` if the frame   |
+      |                              | isn't a scripted frame, or if it's  |
+      |                              | not possible to expose the script   |
+      |                              | to Python for some reason.          |
+      +------------------------------+-------------------------------------+
+      | :const:`lineno`              | Line number of the frame, if the    |
+      |                              | frame is scripted.                  |
+      +------------------------------+-------------------------------------+
+      | :const:`pc`                  | Program counter of the frame; this  |
+      |                              | is an index into the bytecode of    |
+      |                              | the frame's script, if the frame    |
+      |                              | is scripted.                        |
+      +------------------------------+-------------------------------------+
+      | :const:`function`            | The :class:`Function` in which the  |
+      |                              | frame is executing, if any.         |
+      +------------------------------+-------------------------------------+
+      | :const:`caller`              | Dictionary containing information   |
+      |                              | about the stack frame of the        |
+      |                              | caller of this frame. If this frame |
+      |                              | has no caller, this value is        |
+      |                              | ``None``.                           |
+      +------------------------------+-------------------------------------+
+
+      If the context isn't currently executing any code (i.e., the stack
+      is empty), this method returns ``None``.
+
+   .. method:: new_object([private_obj])
+
+      Creates a new :class:`Object` instance and returns
+      it. ``private_obj`` is any Python object that is privately
+      stored within the new JS object; it can be retrieved using
+      :meth:`get_object_private()`.
+
+   .. method:: new_function(func, name)
+
+      Creates a new :class:`Function` instance that wraps the
+      given Python callable.  In JS-land, the function will
+      have the given name.
+
+      When the function is executed from JavaScript, `func`
+      will be passed three positional arguments.
+
+      The first argument is a :class:`Context` that represents the
+      JS context which is calling the function.
+
+      The second argument is an :class:`Object` that represents the
+      value of ``this`` for the duration of the call.
+
+      The third argument is a tuple containing the arguments
+      passed to the function.
+
+      For instance:
+
+        >>> def add(cx, this, args):
+        ...   return args[0] + args[1]
+        >>> cx = pydermonkey.Runtime().new_context()
+        >>> obj = cx.new_object()
+        >>> cx.define_property(obj, 'add', cx.new_function(add, 'add'))
+        >>> cx.evaluate_script(obj, 'add(1, 1);', '<string>', 1)
+        2
+
+   .. method:: define_property(object, name, value)
+
+      Creates a new property on `object`, bypassing any JavaScript setters.
+
+   .. method:: has_property(object, name)
+
+      Returns whether or not `object` has the specified property.
+
+   .. method:: get_property(object, name)
+
+      Finds the specified property on `object` and returns its value,
+      possibly invoking a JavaScript getter.
+
+      Example:
+
+        >>> cx = pydermonkey.Runtime().new_context()
+        >>> obj = cx.new_object()
+        >>> cx.define_property(obj, 'beets', 'i like beets.')
+        >>> cx.get_property(obj, 'beets')
+        u'i like beets.'
+
+      Note also that calling this function on undefined properties
+      yields :data:`undefined`:
+
+        >>> cx.get_property(obj, 'carrots')
+        pydermonkey.undefined
+
+   .. method:: get_object_private(object)
+
+      Returns the ``private_obj`` passed to :meth:`new_object()`
+      when `object` was first created. If it doesn't exist, ``None``
+      is returned.
+
+      If `object` was created with :meth:`new_function()`, then this
+      method returns the Python callable wrapped by `object`.
+
+      This functionality is useful if you want to securely represent
+      Python objects in JS-land.
+
+   .. method:: clear_object_private(object)
+
+      Clears the ``private_obj`` passed to :meth:`new_object()`
+      when `object` was first created. If it doesn't exist, this
+      function returns nothing.
+
+      If `object` was created with :meth:`new_function()`, then this
+      method effectively "unbinds" the Python callable wrapped by
+      `object`. If `object` is later called, an exception will be
+      raised.
+
+   .. method:: evaluate_script(globalobj, code, filename, lineno)
+
+      Evaluates the text `code` using `globalobj` as the global
+      object/scope.
+
+      It's assumed that `code` is coming from the file named by `filename`;
+      the first line of `code` is assumed to be line number `lineno` of
+      `filename`. This metadata is very useful for debugging stack traces,
+      exceptions, and so forth.
+
+      For example:
+
+        >>> cx = pydermonkey.Runtime().new_context()
+        >>> obj = cx.new_object()
+        >>> cx.init_standard_classes(obj)
+        >>> cx.evaluate_script(obj, '5 * Math', '<string>', 1)
+        nan
+
+   .. method:: compile_script(code, filename, lineno)
+
+      Compiles the given string of code and returns a :class:`Script`
+      instance that can be executed via :meth:`execute_script()`.
+
+      `filename` and `lineno` are used just as in
+      :meth:`evaluate_script()`.
+
+   .. method:: execute_script(globalobj, script)
+
+      Executes the code in the given :class:`Script` object, using
+      `globalobj` as the global object/scope, and returns the result.
+
+      For example:
+
+        >>> cx = pydermonkey.Runtime().new_context()
+        >>> obj = cx.new_object()
+        >>> cx.init_standard_classes(obj)
+        >>> script = cx.compile_script('5 * Math', '<string>', 1)
+        >>> cx.execute_script(obj, script)
+        nan
+
+   .. method:: call_function(thisobj, func, args)
+
+      Calls a JavaScript function.
+
+      `thisobj` is an :class:`Object` that will be used as the value
+      of ``this`` when the function executes, `func` is the
+      :class:`Function` to execute, and `args` is a tuple of arguments
+      to pass to the function.
+
+      For instance:
+
+        >>> cx = pydermonkey.Runtime().new_context()
+        >>> obj = cx.new_object()
+        >>> cx.init_standard_classes(obj)
+        >>> Math = cx.get_property(obj, 'Math')
+        >>> floor = cx.get_property(Math, 'floor')
+        >>> cx.call_function(Math, floor, (5.3,))
+        5
+
+   .. method:: init_standard_classes(object)
+
+      Defines the standard JavaScript classes on the given
+      :class:`Object`, such as ``Array``, ``eval``, ``undefined``, and
+      so forth. For more information, see the documentation to
+      `JS_InitStandardClasses()
+      <https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_InitStandardClasses>`_,
+      which this method wraps.
+
+   .. method:: gc()
+
+      Performs garbage collection on the context's JavaScript runtime.
+
+   .. method:: is_exception_pending()
+
+      Returns whether an exception is currently being propagated in
+      the context.
+
+   .. method:: get_pending_exception()
+
+      Returns the current exception being propagated in the context. If
+      no exception is being propagated, this method returns ``None``.
+
+      If you need to disambiguate between whether ``None`` is the
+      pending exception or there is no pending exception, use
+      :meth:`is_exception_pending()`.
+
+   .. method:: set_throw_hook(func)
+
+      Sets the throw hook for the context to the given Python callable.
+      The hook is triggered whenever an exception is thrown in the
+      context.
+
+      `func` takes one argument: the context that triggered it.
+
+      For example, here's a throw hook that prints information about
+      an exception as it's being propagated through the stack:
+
+        >>> def throwhook(cx): 
+        ...   stack = cx.get_stack()
+        ...   if stack['function']:
+        ...     where = stack['function'].name
+        ...   else:
+        ...     where = stack['script'].filename
+        ...   exc = cx.get_pending_exception()
+        ...   print "%s being thrown in %s" % (exc, where)
+
+      Here's the hook in action:
+
+        >>> cx = pydermonkey.Runtime().new_context()
+        >>> cx.set_throw_hook(throwhook)
+        >>> obj = cx.new_object()
+        >>> code = "(function foo() { throw 'oops' })()"
+        >>> try:
+        ...   cx.evaluate_script(obj, code, '<string>', 1)
+        ... except pydermonkey.error, e:
+        ...   print "caught %s" % e.args[0]
+        oops being thrown in foo
+        oops being thrown in <string>
+        caught oops
+
+   .. method:: set_operation_callback(func)
+
+      Sets the operation callback for the context to the given Python
+      callable. The callback can be triggered via
+      :meth:`trigger_operation_callback()`.
+
+      `func` takes one argument: the context that triggered it.
+
+   .. method:: trigger_operation_callback()
+
+      Triggers the context's operation callback. If no callback has
+      yet been set, this function does nothing.
+
+      This function is one of the few thread-safe functions available
+      to a JS runtime, and together with
+      :meth:`set_operation_callback()` can be used to abort the
+      execution of long-running code.
+
+      For instance, we first create an operation callback to stop
+      long-running code by throwing an exception:
+
+        >>> import time, threading
+        >>> cx = pydermonkey.Runtime().new_context()
+        >>> def stop_running_code(cx):
+        ...   raise Exception('JS took too long to execute.')
+        >>> cx.set_operation_callback(stop_running_code)
+
+      Then we create a watchdog thread to trigger the operation
+      callback once a long amount of time has passed:
+
+        >>> def watchdog_thread():
+        ...   time.sleep(0.1)                 # An eternity to a computer!
+        ...   cx.trigger_operation_callback()
+        >>> thread = threading.Thread(target=watchdog_thread)
+        >>> thread.start()
+
+      Now, when we execute code that takes too long to run, it gets
+      aborted:
+
+        >>> try:
+        ...   cx.evaluate_script(cx.new_object(), 'while (1) {}',
+        ...                      '<string>', 1)
+        ... except pydermonkey.error, e:
+        ...   print cx.get_object_private(e.args[0])
+        JS took too long to execute.
+
+.. class:: Runtime()
+
+   Creates a new JavaScript runtime. JS objects created by the runtime
+   may only interact with other JS objects of the same runtime.
+
+   With few exceptions, objects belonging to a runtime can currently
+   only be used in the same thread that the runtime was created
+   in. This may be changed in the future, since SpiderMonkey itself
+   has support for thread safety.
+
+   JS runtimes are weak-referencable.
+
+   .. method:: new_context()
+
+      Creates a new Context object and returns it. Contexts are best
+      conceptualized as threads of execution in a JS runtme; each one
+      has a program counter, a current exception state, and so
+      forth. JS objects may be freely accessed and changed by contexts
+      that are associated with the same JS runtime as the objects.
--- a/docs/rendered/_sources/pymonkey.txt	Sun Aug 30 20:56:43 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,446 +0,0 @@
-:mod:`pymonkey` --- Access SpiderMonkey from Python
-===================================================
-
-.. module:: pymonkey
-   :synopsis: Access SpiderMonkey from Python
-
-.. testsetup:: *
-
-   import pymonkey
-
-This module offers a low-level interface to the `Mozilla SpiderMonkey
-<https://developer.mozilla.org/en/SpiderMonkey>`_ JavaScript engine.
-
-.. exception:: error
-
-   This is the type of any SpiderMonkey-related errors thrown by this
-   module.
-
-   If the error is a wrapped JavaScript exception, the first argument
-   will be the thrown JS exception, and the second argument will be 
-   the JS exception converted to a string. Otherwise, the error
-   will only contain a descriptive string argument.
-
-   For example:
-
-     >>> cx = pymonkey.Runtime().new_context()
-     >>> cx.evaluate_script(cx.new_object(), 'throw 1', '<string>', 1)
-     Traceback (most recent call last):
-     ...
-     error: (1, u'1')
-
-.. data:: undefined
-
-   This is the singleton that represents the JavaScript value
-   ``undefined``, as Python has no equivalent representation
-   (JavaScript's ``null`` is mapped to Python's ``None`` object).
-   For instance:
-
-     >>> cx = pymonkey.Runtime().new_context()
-     >>> cx.evaluate_script(cx.new_object(), '', '<string>', 1)
-     pymonkey.undefined
-
-   This object also has a "falsy" value:
-
-     >>> if not pymonkey.undefined:
-     ...   print "See, it's falsy!"
-     See, it's falsy!
-
-.. class:: Object
-
-   This is the type of JavaScript objects. Such objects can only be
-   created via Pymonkey calls like :meth:`Context.new_object()` or
-   through the execution of JS code, but this type object can be used
-   with Python's built-in :func:`isinstance()` to verify that an
-   object is a JS object, like so:
-
-     >>> obj = pymonkey.Runtime().new_context().new_object()
-     >>> isinstance(obj, pymonkey.Object)
-     True
-
-   Note that :class:`Object` and all its subclasses are
-   identity-preserving when passed between Python and
-   JavaScript code. For instance:
-
-     >>> cx = pymonkey.Runtime().new_context()
-     >>> obj1 = cx.new_object()
-     >>> obj2 = cx.evaluate_script(obj1, 'this', '<string>', 1)
-     >>> obj1 is obj2
-     True
-
-   .. method:: get_runtime()
-
-      Returns the :class:`Runtime` that the object belongs to.
-
-.. class:: Function
-
-   This is the type of JavaScript functions, which is a subtype of
-   :class:`Object`.
-
-   .. data:: filename
-
-      Name of the file that contains the function's original JS source
-      code. If the function isn't a JS function, this value is
-      ``None``.
-
-   .. data:: base_lineno
-
-      The line number at which the function's JS source code begins.
-
-   .. data:: line_extent
-
-      The number of lines comprising the function's JS source code.
-
-   .. data:: is_python
-
-      Whether or not the function is actually implemented in Python.
-      If it is, you can use :meth:`Context.get_object_private()` to
-      retrieve this Python function.
-
-.. class:: Script
-
-   This is the type of compiled JavaScript scripts; it's actually a
-   subtype of :class:`Object`, though when exposed to JS code it
-   doesn't provide access to any special data or functionality.
-
-   Script instances have a read-only buffer interface that exposes
-   their bytecode. This can be accessed by passing an instance to
-   Python's built-in ``buffer()`` function.
-
-   .. data:: filename
-
-      The filename of the script's original source code.
-
-   .. data:: base_lineno
-
-      The line number at which the script's original source code
-      begins.
-
-   .. data:: line_extent
-
-      The number of lines comprising the original source code.
-
-.. class:: Context
-
-   This is the type of JavaScript context objects. Contexts can only
-   be created via a call to :meth:`Runtime.new_context()`, but this
-   type object can be used with Python's built-in :func:`isinstance()`
-   to verify that an object is a context, like so:
-
-     >>> cx = pymonkey.Runtime().new_context()
-     >>> isinstance(cx, pymonkey.Context)
-     True
-
-   JS contexts are weak-referencable.
-
-   .. method:: get_runtime()
-
-      Returns the :class:`Runtime` that the context belongs to.
-
-   .. method:: get_stack()
-
-      Returns a dictionary containing information about the context's
-      current stack.
-
-      The dictionary contains the following string keys:
-
-      +------------------------------+-------------------------------------+
-      | key                          | value                               |
-      +==============================+=====================================+
-      | :const:`script`              | :class:`Script` of the frame.       |
-      |                              | This may be ``None`` if the frame   |
-      |                              | isn't a scripted frame, or if it's  |
-      |                              | not possible to expose the script   |
-      |                              | to Python for some reason.          |
-      +------------------------------+-------------------------------------+
-      | :const:`lineno`              | Line number of the frame, if the    |
-      |                              | frame is scripted.                  |
-      +------------------------------+-------------------------------------+
-      | :const:`pc`                  | Program counter of the frame; this  |
-      |                              | is an index into the bytecode of    |
-      |                              | the frame's script, if the frame    |
-      |                              | is scripted.                        |
-      +------------------------------+-------------------------------------+
-      | :const:`function`            | The :class:`Function` in which the  |
-      |                              | frame is executing, if any.         |
-      +------------------------------+-------------------------------------+
-      | :const:`caller`              | Dictionary containing information   |
-      |                              | about the stack frame of the        |
-      |                              | caller of this frame. If this frame |
-      |                              | has no caller, this value is        |
-      |                              | ``None``.                           |
-      +------------------------------+-------------------------------------+
-
-      If the context isn't currently executing any code (i.e., the stack
-      is empty), this method returns ``None``.
-
-   .. method:: new_object([private_obj])
-
-      Creates a new :class:`Object` instance and returns
-      it. ``private_obj`` is any Python object that is privately
-      stored within the new JS object; it can be retrieved using
-      :meth:`get_object_private()`.
-
-   .. method:: new_function(func, name)
-
-      Creates a new :class:`Function` instance that wraps the
-      given Python callable.  In JS-land, the function will
-      have the given name.
-
-      When the function is executed from JavaScript, `func`
-      will be passed three positional arguments.
-
-      The first argument is a :class:`Context` that represents the
-      JS context which is calling the function.
-
-      The second argument is an :class:`Object` that represents the
-      value of ``this`` for the duration of the call.
-
-      The third argument is a tuple containing the arguments
-      passed to the function.
-
-      For instance:
-
-        >>> def add(cx, this, args):
-        ...   return args[0] + args[1]
-        >>> cx = pymonkey.Runtime().new_context()
-        >>> obj = cx.new_object()
-        >>> cx.define_property(obj, 'add', cx.new_function(add, 'add'))
-        >>> cx.evaluate_script(obj, 'add(1, 1);', '<string>', 1)
-        2
-
-   .. method:: define_property(object, name, value)
-
-      Creates a new property on `object`, bypassing any JavaScript setters.
-
-   .. method:: has_property(object, name)
-
-      Returns whether or not `object` has the specified property.
-
-   .. method:: get_property(object, name)
-
-      Finds the specified property on `object` and returns its value,
-      possibly invoking a JavaScript getter.
-
-      Example:
-
-        >>> cx = pymonkey.Runtime().new_context()
-        >>> obj = cx.new_object()
-        >>> cx.define_property(obj, 'beets', 'i like beets.')
-        >>> cx.get_property(obj, 'beets')
-        u'i like beets.'
-
-      Note also that calling this function on undefined properties
-      yields :data:`undefined`:
-
-        >>> cx.get_property(obj, 'carrots')
-        pymonkey.undefined
-
-   .. method:: get_object_private(object)
-
-      Returns the ``private_obj`` passed to :meth:`new_object()`
-      when `object` was first created. If it doesn't exist, ``None``
-      is returned.
-
-      If `object` was created with :meth:`new_function()`, then this
-      method returns the Python callable wrapped by `object`.
-
-      This functionality is useful if you want to securely represent
-      Python objects in JS-land.
-
-   .. method:: clear_object_private(object)
-
-      Clears the ``private_obj`` passed to :meth:`new_object()`
-      when `object` was first created. If it doesn't exist, this
-      function returns nothing.
-
-      If `object` was created with :meth:`new_function()`, then this
-      method effectively "unbinds" the Python callable wrapped by
-      `object`. If `object` is later called, an exception will be
-      raised.
-
-   .. method:: evaluate_script(globalobj, code, filename, lineno)
-
-      Evaluates the text `code` using `globalobj` as the global
-      object/scope.
-
-      It's assumed that `code` is coming from the file named by `filename`;
-      the first line of `code` is assumed to be line number `lineno` of
-      `filename`. This metadata is very useful for debugging stack traces,
-      exceptions, and so forth.
-
-      For example:
-
-        >>> cx = pymonkey.Runtime().new_context()
-        >>> obj = cx.new_object()
-        >>> cx.init_standard_classes(obj)
-        >>> cx.evaluate_script(obj, '5 * Math', '<string>', 1)
-        nan
-
-   .. method:: compile_script(code, filename, lineno)
-
-      Compiles the given string of code and returns a :class:`Script`
-      instance that can be executed via :meth:`execute_script()`.
-
-      `filename` and `lineno` are used just as in
-      :meth:`evaluate_script()`.
-
-   .. method:: execute_script(globalobj, script)
-
-      Executes the code in the given :class:`Script` object, using
-      `globalobj` as the global object/scope, and returns the result.
-
-      For example:
-
-        >>> cx = pymonkey.Runtime().new_context()
-        >>> obj = cx.new_object()
-        >>> cx.init_standard_classes(obj)
-        >>> script = cx.compile_script('5 * Math', '<string>', 1)
-        >>> cx.execute_script(obj, script)
-        nan
-
-   .. method:: call_function(thisobj, func, args)
-
-      Calls a JavaScript function.
-
-      `thisobj` is an :class:`Object` that will be used as the value
-      of ``this`` when the function executes, `func` is the
-      :class:`Function` to execute, and `args` is a tuple of arguments
-      to pass to the function.
-
-      For instance:
-
-        >>> cx = pymonkey.Runtime().new_context()
-        >>> obj = cx.new_object()
-        >>> cx.init_standard_classes(obj)
-        >>> Math = cx.get_property(obj, 'Math')
-        >>> floor = cx.get_property(Math, 'floor')
-        >>> cx.call_function(Math, floor, (5.3,))
-        5
-
-   .. method:: init_standard_classes(object)
-
-      Defines the standard JavaScript classes on the given
-      :class:`Object`, such as ``Array``, ``eval``, ``undefined``, and
-      so forth. For more information, see the documentation to
-      `JS_InitStandardClasses()
-      <https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_InitStandardClasses>`_,
-      which this method wraps.
-
-   .. method:: gc()
-
-      Performs garbage collection on the context's JavaScript runtime.
-
-   .. method:: is_exception_pending()
-
-      Returns whether an exception is currently being propagated in
-      the context.
-
-   .. method:: get_pending_exception()
-
-      Returns the current exception being propagated in the context. If
-      no exception is being propagated, this method returns ``None``.
-
-      If you need to disambiguate between whether ``None`` is the
-      pending exception or there is no pending exception, use
-      :meth:`is_exception_pending()`.
-
-   .. method:: set_throw_hook(func)
-
-      Sets the throw hook for the context to the given Python callable.
-      The hook is triggered whenever an exception is thrown in the
-      context.
-
-      `func` takes one argument: the context that triggered it.
-
-      For example, here's a throw hook that prints information about
-      an exception as it's being propagated through the stack:
-
-        >>> def throwhook(cx): 
-        ...   stack = cx.get_stack()
-        ...   if stack['function']:
-        ...     where = stack['function'].name
-        ...   else:
-        ...     where = stack['script'].filename
-        ...   exc = cx.get_pending_exception()
-        ...   print "%s being thrown in %s" % (exc, where)
-
-      Here's the hook in action:
-
-        >>> cx = pymonkey.Runtime().new_context()
-        >>> cx.set_throw_hook(throwhook)
-        >>> obj = cx.new_object()
-        >>> code = "(function foo() { throw 'oops' })()"
-        >>> try:
-        ...   cx.evaluate_script(obj, code, '<string>', 1)
-        ... except pymonkey.error, e:
-        ...   print "caught %s" % e.args[0]
-        oops being thrown in foo
-        oops being thrown in <string>
-        caught oops
-
-   .. method:: set_operation_callback(func)
-
-      Sets the operation callback for the context to the given Python
-      callable. The callback can be triggered via
-      :meth:`trigger_operation_callback()`.
-
-      `func` takes one argument: the context that triggered it.
-
-   .. method:: trigger_operation_callback()
-
-      Triggers the context's operation callback. If no callback has
-      yet been set, this function does nothing.
-
-      This function is one of the few thread-safe functions available
-      to a JS runtime, and together with
-      :meth:`set_operation_callback()` can be used to abort the
-      execution of long-running code.
-
-      For instance, we first create an operation callback to stop
-      long-running code by throwing an exception:
-
-        >>> import time, threading
-        >>> cx = pymonkey.Runtime().new_context()
-        >>> def stop_running_code(cx):
-        ...   raise Exception('JS took too long to execute.')
-        >>> cx.set_operation_callback(stop_running_code)
-
-      Then we create a watchdog thread to trigger the operation
-      callback once a long amount of time has passed:
-
-        >>> def watchdog_thread():
-        ...   time.sleep(0.1)                 # An eternity to a computer!
-        ...   cx.trigger_operation_callback()
-        >>> thread = threading.Thread(target=watchdog_thread)
-        >>> thread.start()
-
-      Now, when we execute code that takes too long to run, it gets
-      aborted:
-
-        >>> try:
-        ...   cx.evaluate_script(cx.new_object(), 'while (1) {}',
-        ...                      '<string>', 1)
-        ... except pymonkey.error, e:
-        ...   print cx.get_object_private(e.args[0])
-        JS took too long to execute.
-
-.. class:: Runtime()
-
-   Creates a new JavaScript runtime. JS objects created by the runtime
-   may only interact with other JS objects of the same runtime.
-
-   With few exceptions, objects belonging to a runtime can currently
-   only be used in the same thread that the runtime was created
-   in. This may be changed in the future, since SpiderMonkey itself
-   has support for thread safety.
-
-   JS runtimes are weak-referencable.
-
-   .. method:: new_context()
-
-      Creates a new Context object and returns it. Contexts are best
-      conceptualized as threads of execution in a JS runtme; each one
-      has a program counter, a current exception state, and so
-      forth. JS objects may be freely accessed and changed by contexts
-      that are associated with the same JS runtime as the objects.
--- a/docs/rendered/genindex.html	Sun Aug 30 20:56:43 2009 -0700
+++ b/docs/rendered/genindex.html	Tue Sep 01 03:07:24 2009 -0700
@@ -5,7 +5,7 @@
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     
-    <title>Index &mdash; Pymonkey v0.0.1 documentation</title>
+    <title>Index &mdash; Pydermonkey v0.0.1 documentation</title>
     <link rel="stylesheet" href="_static/default.css" type="text/css" />
     <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
     <script type="text/javascript">
@@ -19,7 +19,7 @@
     </script>
     <script type="text/javascript" src="_static/jquery.js"></script>
     <script type="text/javascript" src="_static/doctools.js"></script>
-    <link rel="top" title="Pymonkey v0.0.1 documentation" href="index.html" /> 
+    <link rel="top" title="Pydermonkey v0.0.1 documentation" href="index.html" /> 
   </head>
   <body>
     <div class="related">
@@ -31,7 +31,7 @@
         <li class="right" >
           <a href="modindex.html" title="Global Module Index"
              accesskey="M">modules</a> |</li>
-        <li><a href="index.html">Pymonkey v0.0.1 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Pydermonkey v0.0.1 documentation</a> &raquo;</li> 
       </ul>
     </div>  
 
@@ -52,123 +52,123 @@
 <table width="100%" class="indextable"><tr><td width="33%" valign="top">
 <dl>
 
-<dt><a href="pymonkey.html#pymonkey.Context.call_function">call_function() (pymonkey.Context method)</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Context.clear_object_private">clear_object_private() (pymonkey.Context method)</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Context.compile_script">compile_script() (pymonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
-<dt><a href="pymonkey.html#pymonkey.Context">Context (class in pymonkey)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Context.call_function">call_function() (pydermonkey.Context method)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Context.clear_object_private">clear_object_private() (pydermonkey.Context method)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Context.compile_script">compile_script() (pydermonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="pydermonkey.html#pydermonkey.Context">Context (class in pydermonkey)</a></dt>
 </dl></td></tr></table>
 
 <h2 id="D">D</h2>
 <table width="100%" class="indextable"><tr><td width="33%" valign="top">
 <dl>
 
-<dt><a href="pymonkey.html#pymonkey.Context.define_property">define_property() (pymonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="pydermonkey.html#pydermonkey.Context.define_property">define_property() (pydermonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
 </dl></td></tr></table>
 
 <h2 id="E">E</h2>
 <table width="100%" class="indextable"><tr><td width="33%" valign="top">
 <dl>
 
-<dt><a href="pymonkey.html#pymonkey.error">error</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Context.evaluate_script">evaluate_script() (pymonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
-<dt><a href="pymonkey.html#pymonkey.Context.execute_script">execute_script() (pymonkey.Context method)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.error">error</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Context.evaluate_script">evaluate_script() (pydermonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="pydermonkey.html#pydermonkey.Context.execute_script">execute_script() (pydermonkey.Context method)</a></dt>
 </dl></td></tr></table>
 
 <h2 id="F">F</h2>
 <table width="100%" class="indextable"><tr><td width="33%" valign="top">
 <dl>
 
-<dt><a href="pymonkey.html#pymonkey.Function">Function (class in pymonkey)</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Function.base_lineno">Function.base_lineno (in module pymonkey)</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Function.filename">Function.filename (in module pymonkey)</a></dt></dl></td><td width="33%" valign="top"><dl>
-<dt><a href="pymonkey.html#pymonkey.Function.is_python">Function.is_python (in module pymonkey)</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Function.line_extent">Function.line_extent (in module pymonkey)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Function">Function (class in pydermonkey)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Function.base_lineno">Function.base_lineno (in module pydermonkey)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Function.filename">Function.filename (in module pydermonkey)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="pydermonkey.html#pydermonkey.Function.is_python">Function.is_python (in module pydermonkey)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Function.line_extent">Function.line_extent (in module pydermonkey)</a></dt>
 </dl></td></tr></table>
 
 <h2 id="G">G</h2>
 <table width="100%" class="indextable"><tr><td width="33%" valign="top">
 <dl>
 
-<dt><a href="pymonkey.html#pymonkey.Context.gc">gc() (pymonkey.Context method)</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Context.get_object_private">get_object_private() (pymonkey.Context method)</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Context.get_pending_exception">get_pending_exception() (pymonkey.Context method)</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Context.get_property">get_property() (pymonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
-<dt><a href="pymonkey.html#pymonkey.Context.get_runtime">get_runtime() (pymonkey.Context method)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Context.gc">gc() (pydermonkey.Context method)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Context.get_object_private">get_object_private() (pydermonkey.Context method)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Context.get_pending_exception">get_pending_exception() (pydermonkey.Context method)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Context.get_property">get_property() (pydermonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="pydermonkey.html#pydermonkey.Context.get_runtime">get_runtime() (pydermonkey.Context method)</a></dt>
   <dd><dl>
-    <dt><a href="pymonkey.html#pymonkey.Object.get_runtime">(pymonkey.Object method)</a></dt>
+    <dt><a href="pydermonkey.html#pydermonkey.Object.get_runtime">(pydermonkey.Object method)</a></dt>
   </dl></dd>
-<dt><a href="pymonkey.html#pymonkey.Context.get_stack">get_stack() (pymonkey.Context method)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Context.get_stack">get_stack() (pydermonkey.Context method)</a></dt>
 </dl></td></tr></table>
 
 <h2 id="H">H</h2>
 <table width="100%" class="indextable"><tr><td width="33%" valign="top">
 <dl>
 
-<dt><a href="pymonkey.html#pymonkey.Context.has_property">has_property() (pymonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="pydermonkey.html#pydermonkey.Context.has_property">has_property() (pydermonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
 </dl></td></tr></table>
 
 <h2 id="I">I</h2>
 <table width="100%" class="indextable"><tr><td width="33%" valign="top">
 <dl>
 
-<dt><a href="pymonkey.html#pymonkey.Context.init_standard_classes">init_standard_classes() (pymonkey.Context method)</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Context.is_exception_pending">is_exception_pending() (pymonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="pydermonkey.html#pydermonkey.Context.init_standard_classes">init_standard_classes() (pydermonkey.Context method)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Context.is_exception_pending">is_exception_pending() (pydermonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
 </dl></td></tr></table>
 
 <h2 id="N">N</h2>
 <table width="100%" class="indextable"><tr><td width="33%" valign="top">
 <dl>
 
-<dt><a href="pymonkey.html#pymonkey.Runtime.new_context">new_context() (pymonkey.Runtime method)</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Context.new_function">new_function() (pymonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
-<dt><a href="pymonkey.html#pymonkey.Context.new_object">new_object() (pymonkey.Context method)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Runtime.new_context">new_context() (pydermonkey.Runtime method)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Context.new_function">new_function() (pydermonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="pydermonkey.html#pydermonkey.Context.new_object">new_object() (pydermonkey.Context method)</a></dt>
 </dl></td></tr></table>
 
 <h2 id="O">O</h2>
 <table width="100%" class="indextable"><tr><td width="33%" valign="top">
 <dl>
 
-<dt><a href="pymonkey.html#pymonkey.Object">Object (class in pymonkey)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="pydermonkey.html#pydermonkey.Object">Object (class in pydermonkey)</a></dt></dl></td><td width="33%" valign="top"><dl>
 </dl></td></tr></table>
 
 <h2 id="P">P</h2>
 <table width="100%" class="indextable"><tr><td width="33%" valign="top">
 <dl>
 
-<dt><a href="pymonkey.html#module-pymonkey">pymonkey (module)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="pydermonkey.html#module-pydermonkey">pydermonkey (module)</a></dt></dl></td><td width="33%" valign="top"><dl>
 </dl></td></tr></table>
 
 <h2 id="R">R</h2>
 <table width="100%" class="indextable"><tr><td width="33%" valign="top">
 <dl>
 
-<dt><a href="pymonkey.html#pymonkey.Runtime">Runtime (class in pymonkey)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="pydermonkey.html#pydermonkey.Runtime">Runtime (class in pydermonkey)</a></dt></dl></td><td width="33%" valign="top"><dl>
 </dl></td></tr></table>
 
 <h2 id="S">S</h2>
 <table width="100%" class="indextable"><tr><td width="33%" valign="top">
 <dl>
 
-<dt><a href="pymonkey.html#pymonkey.Script">Script (class in pymonkey)</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Script.base_lineno">Script.base_lineno (in module pymonkey)</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Script.filename">Script.filename (in module pymonkey)</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Script.line_extent">Script.line_extent (in module pymonkey)</a></dt></dl></td><td width="33%" valign="top"><dl>
-<dt><a href="pymonkey.html#pymonkey.Context.set_operation_callback">set_operation_callback() (pymonkey.Context method)</a></dt>
-<dt><a href="pymonkey.html#pymonkey.Context.set_throw_hook">set_throw_hook() (pymonkey.Context method)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Script">Script (class in pydermonkey)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Script.base_lineno">Script.base_lineno (in module pydermonkey)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Script.filename">Script.filename (in module pydermonkey)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Script.line_extent">Script.line_extent (in module pydermonkey)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="pydermonkey.html#pydermonkey.Context.set_operation_callback">set_operation_callback() (pydermonkey.Context method)</a></dt>
+<dt><a href="pydermonkey.html#pydermonkey.Context.set_throw_hook">set_throw_hook() (pydermonkey.Context method)</a></dt>
 </dl></td></tr></table>
 
 <h2 id="T">T</h2>
 <table width="100%" class="indextable"><tr><td width="33%" valign="top">
 <dl>
 
-<dt><a href="pymonkey.html#pymonkey.Context.trigger_operation_callback">trigger_operation_callback() (pymonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="pydermonkey.html#pydermonkey.Context.trigger_operation_callback">trigger_operation_callback() (pydermonkey.Context method)</a></dt></dl></td><td width="33%" valign="top"><dl>
 </dl></td></tr></table>
 
 <h2 id="U">U</h2>
 <table width="100%" class="indextable"><tr><td width="33%" valign="top">
 <dl>
 
-<dt><a href="pymonkey.html#pymonkey.undefined">undefined (in module pymonkey)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="pydermonkey.html#pydermonkey.undefined">undefined (in module pydermonkey)</a></dt></dl></td><td width="33%" valign="top"><dl>
 </dl></td></tr></table>
 
 
@@ -207,7 +207,7 @@
         <li class="right" >
           <a href="modindex.html" title="Global Module Index"
              >modules</a> |</li>
-        <li><a href="index.html">Pymonkey v0.0.1 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Pydermonkey v0.0.1 documentation</a> &raquo;</li> 
       </ul>
     </div>
     <div class="footer">
--- a/docs/rendered/index.html	Sun Aug 30 20:56:43 2009 -0700
+++ b/docs/rendered/index.html	Tue Sep 01 03:07:24 2009 -0700
@@ -5,7 +5,7 @@
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     
-    <title>Pymonkey Documentation &mdash; Pymonkey v0.0.1 documentation</title>
+    <title>Pydermonkey Documentation &mdash; Pydermonkey v0.0.1 documentation</title>
     <link rel="stylesheet" href="_static/default.css" type="text/css" />
     <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
     <script type="text/javascript">
@@ -19,8 +19,8 @@
     </script>
     <script type="text/javascript" src="_static/jquery.js"></script>
     <script type="text/javascript" src="_static/doctools.js"></script>
-    <link rel="top" title="Pymonkey v0.0.1 documentation" href="" />
-    <link rel="next" title="pymonkey — Access SpiderMonkey from Python" href="pymonkey.html" /> 
+    <link rel="top" title="Pydermonkey v0.0.1 documentation" href="" />
+    <link rel="next" title="pydermonkey — Access SpiderMonkey from Python" href="pydermonkey.html" /> 
   </head>
   <body>
     <div class="related">
@@ -33,9 +33,9 @@
           <a href="modindex.html" title="Global Module Index"
              accesskey="M">modules</a> |</li>
         <li class="right" >
-          <a href="pymonkey.html" title="pymonkey — Access SpiderMonkey from Python"
+          <a href="pydermonkey.html" title="pydermonkey — Access SpiderMonkey from Python"
              accesskey="N">next</a> |</li>
-        <li><a href="">Pymonkey v0.0.1 documentation</a> &raquo;</li> 
+        <li><a href="">Pydermonkey v0.0.1 documentation</a> &raquo;</li> 
       </ul>
     </div>  
 
@@ -44,13 +44,13 @@
         <div class="bodywrapper">
           <div class="body">
             
-  <div class="section" id="pymonkey-documentation">
-<h1>Pymonkey Documentation<a class="headerlink" href="#pymonkey-documentation" title="Permalink to this headline">¶</a></h1>
-<p>Pymonkey is a Python C extension module to expose the <a class="reference" href="https://developer.mozilla.org/en/SpiderMonkey">Mozilla
+  <div class="section" id="pydermonkey-documentation">
+<h1>Pydermonkey Documentation<a class="headerlink" href="#pydermonkey-documentation" title="Permalink to this headline">¶</a></h1>
+<p>Pydermonkey is a Python C extension module to expose the <a class="reference" href="https://developer.mozilla.org/en/SpiderMonkey">Mozilla
 SpiderMonkey</a> engine
 to Python.</p>
 <ul>
-<li class="toctree-l1"><a class="reference" href="pymonkey.html"><tt class="docutils literal"><span class="pre">pymonkey</span></tt> &#8212; Access SpiderMonkey from Python</a></li>
+<li class="toctree-l1"><a class="reference" href="pydermonkey.html"><tt class="docutils literal"><span class="pre">pydermonkey</span></tt> &#8212; Access SpiderMonkey from Python</a></li>
 </ul>
 <p>Rationale and Goals:</p>
 <ul>
@@ -69,17 +69,17 @@
 would be very useful. Standards-based solutions like <a class="reference" href="https://wiki.mozilla.org/ServerJS">ServerJS</a> are currently paving the way
 in this field. There&#8217;s Java-based solutions like Rhino out there,
 but nothing really mature is available for the Python
-world. Ideally, Pymonkey should enable a Python programmer to create
+world. Ideally, Pydermonkey should enable a Python programmer to create
 a custom sandboxed environment for executing JS code without needing
 to write any C.</p>
 </li>
-<li><p class="first">Pymonkey should have awesome Sphinx documentation with doctests and
+<li><p class="first">Pydermonkey should have awesome Sphinx documentation with doctests and
 all the trappings of a model Python package. Not only should it be
 easy for Python programmers to learn how to use the module, but it
 should also be easy for them to learn more about how SpiderMonkey
 works by reading the documentation and playing around with the code.</p>
 </li>
-<li><p class="first">Pymonkey needs to have outstanding developer ergonomics. Full
+<li><p class="first">Pydermonkey needs to have outstanding developer ergonomics. Full
 cross-language stack tracebacks should be available, for instance,
 and developers should be able to easily debug. Access to memory
 profiling facilities in JS-land is a must.</p>
@@ -103,7 +103,7 @@
 </ul>
 <div class="section" id="building-testing-and-installing">
 <h2>Building, Testing, and Installing<a class="headerlink" href="#building-testing-and-installing" title="Permalink to this headline">¶</a></h2>
-<p>From the root of your pymonkey repository, run:</p>
+<p>From the root of your pydermonkey repository, run:</p>
 <div class="highlight-python"><pre>python setup.py build test</pre>
 </div>
 <p>This will fetch and compile SpiderMonkey, build the C extension, and
@@ -116,7 +116,7 @@
 <div class="section" id="challenges">
 <h2>Challenges<a class="headerlink" href="#challenges" title="Permalink to this headline">¶</a></h2>
 <p>There&#8217;s a number of challenges that need to be resolved before
-pymonkey can be really usable. Here&#8217;s some of them.</p>
+pydermonkey can be really usable. Here&#8217;s some of them.</p>
 <p><strong>Garbage Collection</strong></p>
 <p>Python&#8217;s garbage collection uses reference counting, whereas
 SpiderMonkey&#8217;s is mark-and-sweep. It&#8217;s possible for there to be
@@ -126,7 +126,7 @@
 reference counting too&#8211;so detecting such cycles will probably involve
 creating something akin to <a class="reference" href="https://developer.mozilla.org/en/Interfacing_with_the_XPCOM_cycle_collector">XPCOM&#8217;s cycle collector</a>.</p>
 <p>For the time being, however, such cycles can be manually broken via
-<a title="pymonkey.Context.clear_object_private" class="reference" href="pymonkey.html#pymonkey.Context.clear_object_private"><tt class="xref docutils literal"><span class="pre">pymonkey.Context.clear_object_private()</span></tt></a> on valid objects and functions.</p>
+<a title="pydermonkey.Context.clear_object_private" class="reference" href="pydermonkey.html#pydermonkey.Context.clear_object_private"><tt class="xref docutils literal"><span class="pre">pydermonkey.Context.clear_object_private()</span></tt></a> on valid objects and functions.</p>
 </div>
 <div class="section" id="indices-and-tables">
 <h2>Indices and Tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h2>
@@ -146,7 +146,7 @@
         <div class="sphinxsidebarwrapper">
             <h3><a href="">Table Of Contents</a></h3>
             <ul>
-<li><a class="reference" href="">Pymonkey Documentation</a><ul>
+<li><a class="reference" href="">Pydermonkey Documentation</a><ul>
 <li><a class="reference" href="#building-testing-and-installing">Building, Testing, and Installing</a></li>
 <li><a class="reference" href="#challenges">Challenges</a></li>
 <li><a class="reference" href="#indices-and-tables">Indices and Tables</a></li>
@@ -155,8 +155,8 @@
 </ul>
 
             <h4>Next topic</h4>
-            <p class="topless"><a href="pymonkey.html"
-                                  title="next chapter"><tt class="docutils literal"><span class="pre">pymonkey</span></tt> &#8212; Access SpiderMonkey from Python</a></p>
+            <p class="topless"><a href="pydermonkey.html"
+                                  title="next chapter"><tt class="docutils literal"><span class="pre">pydermonkey</span></tt> &#8212; Access SpiderMonkey from Python</a></p>
             <h3>This Page</h3>
             <ul class="this-page-menu">
               <li><a href="_sources/index.txt"
@@ -189,9 +189,9 @@
           <a href="modindex.html" title="Global Module Index"
              >modules</a> |</li>
         <li class="right" >
-          <a href="pymonkey.html" title="pymonkey — Access SpiderMonkey from Python"
+          <a href="pydermonkey.html" title="pydermonkey — Access SpiderMonkey from Python"
              >next</a> |</li>
-        <li><a href="">Pymonkey v0.0.1 documentation</a> &raquo;</li> 
+        <li><a href="">Pydermonkey v0.0.1 documentation</a> &raquo;</li> 
       </ul>
     </div>
     <div class="footer">
--- a/docs/rendered/modindex.html	Sun Aug 30 20:56:43 2009 -0700
+++ b/docs/rendered/modindex.html	Tue Sep 01 03:07:24 2009 -0700
@@ -5,7 +5,7 @@
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     
-    <title>Global Module Index &mdash; Pymonkey v0.0.1 documentation</title>
+    <title>Global Module Index &mdash; Pydermonkey v0.0.1 documentation</title>
     <link rel="stylesheet" href="_static/default.css" type="text/css" />
     <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
     <script type="text/javascript">
@@ -19,7 +19,7 @@
     </script>
     <script type="text/javascript" src="_static/jquery.js"></script>
     <script type="text/javascript" src="_static/doctools.js"></script>
-    <link rel="top" title="Pymonkey v0.0.1 documentation" href="index.html" />
+    <link rel="top" title="Pydermonkey v0.0.1 documentation" href="index.html" />
  
 
     <script type="text/javascript">
@@ -38,7 +38,7 @@
         <li class="right" >
           <a href="" title="Global Module Index"
              accesskey="M">modules</a> |</li>
-        <li><a href="index.html">Pymonkey v0.0.1 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Pydermonkey v0.0.1 documentation</a> &raquo;</li> 
       </ul>
     </div>  
 
@@ -56,7 +56,7 @@
    <tr class="cap"><td></td><td><a name="cap-P"><strong>P</strong></a></td><td></td></tr><tr>
      <td></td>
      <td>
-     <a href="pymonkey.html#module-pymonkey"><tt class="xref">pymonkey</tt></a></td><td>
+     <a href="pydermonkey.html#module-pydermonkey"><tt class="xref">pydermonkey</tt></a></td><td>
      <em>Access SpiderMonkey from Python</em></td></tr>
    </table>
 
@@ -92,7 +92,7 @@
         <li class="right" >
           <a href="" title="Global Module Index"
              >modules</a> |</li>
-        <li><a href="index.html">Pymonkey v0.0.1 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Pydermonkey v0.0.1 documentation</a> &raquo;</li> 
       </ul>
     </div>
     <div class="footer">
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/rendered/pydermonkey.html	Tue Sep 01 03:07:24 2009 -0700
@@ -0,0 +1,593 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>pydermonkey — Access SpiderMonkey from Python &mdash; Pydermonkey v0.0.1 documentation</title>
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '0.0.1',
+        COLLAPSE_MODINDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="top" title="Pydermonkey v0.0.1 documentation" href="index.html" />
+    <link rel="prev" title="Pydermonkey Documentation" href="index.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="modindex.html" title="Global Module Index"
+             accesskey="M">modules</a> |</li>
+        <li class="right" >
+          <a href="index.html" title="Pydermonkey Documentation"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">Pydermonkey v0.0.1 documentation</a> &raquo;</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="module-pydermonkey">
+<h1><tt class="xref docutils literal"><span class="pre">pydermonkey</span></tt> &#8212; Access SpiderMonkey from Python<a class="headerlink" href="#module-pydermonkey" title="Permalink to this headline">¶</a></h1>
+<p>This module offers a low-level interface to the <a class="reference" href="https://developer.mozilla.org/en/SpiderMonkey">Mozilla SpiderMonkey</a> JavaScript engine.</p>
+<dl class="exception">
+<dt id="pydermonkey.error">
+<em class="property">
+exception </em><tt class="descclassname">pydermonkey.</tt><tt class="descname">error</tt><a class="headerlink" href="#pydermonkey.error" title="Permalink to this definition">¶</a></dt>
+<dd><p>This is the type of any SpiderMonkey-related errors thrown by this
+module.</p>
+<p>If the error is a wrapped JavaScript exception, the first argument
+will be the thrown JS exception, and the second argument will be
+the JS exception converted to a string. Otherwise, the error
+will only contain a descriptive string argument.</p>
+<p>For example:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">evaluate_script</span><span class="p">(</span><span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">(),</span> <span class="s">&#39;throw 1&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
+<span class="gp">...</span>
+<span class="go">error: (1, u&#39;1&#39;)</span>
+</pre></div>
+</div>
+</dd></dl>
+
+<dl class="data">
+<dt id="pydermonkey.undefined">
+<tt class="descclassname">pydermonkey.</tt><tt class="descname">undefined</tt><a class="headerlink" href="#pydermonkey.undefined" title="Permalink to this definition">¶</a></dt>
+<dd><p>This is the singleton that represents the JavaScript value
+<tt class="docutils literal"><span class="pre">undefined</span></tt>, as Python has no equivalent representation
+(JavaScript&#8217;s <tt class="docutils literal"><span class="pre">null</span></tt> is mapped to Python&#8217;s <tt class="xref docutils literal"><span class="pre">None</span></tt> object).
+For instance:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">evaluate_script</span><span class="p">(</span><span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">(),</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
+<span class="go">pydermonkey.undefined</span>
+</pre></div>
+</div>
+<p>This object also has a &#8220;falsy&#8221; value:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">if</span> <span class="ow">not</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">undefined</span><span class="p">:</span>
+<span class="gp">... </span>  <span class="k">print</span> <span class="s">&quot;See, it&#39;s falsy!&quot;</span>
+<span class="go">See, it&#39;s falsy!</span>
+</pre></div>
+</div>
+</dd></dl>
+
+<dl class="class">
+<dt id="pydermonkey.Object">
+<em class="property">
+class </em><tt class="descclassname">pydermonkey.</tt><tt class="descname">Object</tt><a class="headerlink" href="#pydermonkey.Object" title="Permalink to this definition">¶</a></dt>
+<dd><p>This is the type of JavaScript objects. Such objects can only be
+created via Pydermonkey calls like <a title="pydermonkey.Context.new_object" class="reference" href="#pydermonkey.Context.new_object"><tt class="xref docutils literal"><span class="pre">Context.new_object()</span></tt></a> or
+through the execution of JS code, but this type object can be used
+with Python&#8217;s built-in <tt class="xref docutils literal"><span class="pre">isinstance()</span></tt> to verify that an
+object is a JS object, like so:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">Object</span><span class="p">)</span>
+<span class="go">True</span>
+</pre></div>
+</div>
+<p>Note that <a title="pydermonkey.Object" class="reference" href="#pydermonkey.Object"><tt class="xref docutils literal"><span class="pre">Object</span></tt></a> and all its subclasses are
+identity-preserving when passed between Python and
+JavaScript code. For instance:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">obj1</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">obj2</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">evaluate_script</span><span class="p">(</span><span class="n">obj1</span><span class="p">,</span> <span class="s">&#39;this&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">obj1</span> <span class="ow">is</span> <span class="n">obj2</span>
+<span class="go">True</span>
+</pre></div>
+</div>
+<dl class="method">
+<dt id="pydermonkey.Object.get_runtime">
+<tt class="descname">get_runtime</tt><big>(</big><big>)</big><a class="headerlink" href="#pydermonkey.Object.get_runtime" title="Permalink to this definition">¶</a></dt>
+<dd>Returns the <a title="pydermonkey.Runtime" class="reference" href="#pydermonkey.Runtime"><tt class="xref docutils literal"><span class="pre">Runtime</span></tt></a> that the object belongs to.</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="pydermonkey.Function">
+<em class="property">
+class </em><tt class="descclassname">pydermonkey.</tt><tt class="descname">Function</tt><a class="headerlink" href="#pydermonkey.Function" title="Permalink to this definition">¶</a></dt>
+<dd><p>This is the type of JavaScript functions, which is a subtype of
+<a title="pydermonkey.Object" class="reference" href="#pydermonkey.Object"><tt class="xref docutils literal"><span class="pre">Object</span></tt></a>.</p>
+<dl class="data">
+<dt id="pydermonkey.Function.filename">
+<tt class="descname">filename</tt><a class="headerlink" href="#pydermonkey.Function.filename" title="Permalink to this definition">¶</a></dt>
+<dd>Name of the file that contains the function&#8217;s original JS source
+code. If the function isn&#8217;t a JS function, this value is
+<tt class="xref docutils literal"><span class="pre">None</span></tt>.</dd></dl>
+
+<dl class="data">
+<dt id="pydermonkey.Function.base_lineno">
+<tt class="descname">base_lineno</tt><a class="headerlink" href="#pydermonkey.Function.base_lineno" title="Permalink to this definition">¶</a></dt>
+<dd>The line number at which the function&#8217;s JS source code begins.</dd></dl>
+
+<dl class="data">
+<dt id="pydermonkey.Function.line_extent">
+<tt class="descname">line_extent</tt><a class="headerlink" href="#pydermonkey.Function.line_extent" title="Permalink to this definition">¶</a></dt>
+<dd>The number of lines comprising the function&#8217;s JS source code.</dd></dl>
+
+<dl class="data">
+<dt id="pydermonkey.Function.is_python">
+<tt class="descname">is_python</tt><a class="headerlink" href="#pydermonkey.Function.is_python" title="Permalink to this definition">¶</a></dt>
+<dd>Whether or not the function is actually implemented in Python.
+If it is, you can use <a title="pydermonkey.Context.get_object_private" class="reference" href="#pydermonkey.Context.get_object_private"><tt class="xref docutils literal"><span class="pre">Context.get_object_private()</span></tt></a> to
+retrieve this Python function.</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="pydermonkey.Script">
+<em class="property">
+class </em><tt class="descclassname">pydermonkey.</tt><tt class="descname">Script</tt><a class="headerlink" href="#pydermonkey.Script" title="Permalink to this definition">¶</a></dt>
+<dd><p>This is the type of compiled JavaScript scripts; it&#8217;s actually a
+subtype of <a title="pydermonkey.Object" class="reference" href="#pydermonkey.Object"><tt class="xref docutils literal"><span class="pre">Object</span></tt></a>, though when exposed to JS code it
+doesn&#8217;t provide access to any special data or functionality.</p>
+<p>Script instances have a read-only buffer interface that exposes
+their bytecode. This can be accessed by passing an instance to
+Python&#8217;s built-in <tt class="docutils literal"><span class="pre">buffer()</span></tt> function.</p>
+<dl class="data">
+<dt id="pydermonkey.Script.filename">
+<tt class="descname">filename</tt><a class="headerlink" href="#pydermonkey.Script.filename" title="Permalink to this definition">¶</a></dt>
+<dd>The filename of the script&#8217;s original source code.</dd></dl>
+
+<dl class="data">
+<dt id="pydermonkey.Script.base_lineno">
+<tt class="descname">base_lineno</tt><a class="headerlink" href="#pydermonkey.Script.base_lineno" title="Permalink to this definition">¶</a></dt>
+<dd>The line number at which the script&#8217;s original source code
+begins.</dd></dl>
+
+<dl class="data">
+<dt id="pydermonkey.Script.line_extent">
+<tt class="descname">line_extent</tt><a class="headerlink" href="#pydermonkey.Script.line_extent" title="Permalink to this definition">¶</a></dt>
+<dd>The number of lines comprising the original source code.</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="pydermonkey.Context">
+<em class="property">
+class </em><tt class="descclassname">pydermonkey.</tt><tt class="descname">Context</tt><a class="headerlink" href="#pydermonkey.Context" title="Permalink to this definition">¶</a></dt>
+<dd><p>This is the type of JavaScript context objects. Contexts can only
+be created via a call to <a title="pydermonkey.Runtime.new_context" class="reference" href="#pydermonkey.Runtime.new_context"><tt class="xref docutils literal"><span class="pre">Runtime.new_context()</span></tt></a>, but this
+type object can be used with Python&#8217;s built-in <tt class="xref docutils literal"><span class="pre">isinstance()</span></tt>
+to verify that an object is a context, like so:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="nb">isinstance</span><span class="p">(</span><span class="n">cx</span><span class="p">,</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">Context</span><span class="p">)</span>
+<span class="go">True</span>
+</pre></div>
+</div>
+<p>JS contexts are weak-referencable.</p>
+<dl class="method">
+<dt id="pydermonkey.Context.get_runtime">
+<tt class="descname">get_runtime</tt><big>(</big><big>)</big><a class="headerlink" href="#pydermonkey.Context.get_runtime" title="Permalink to this definition">¶</a></dt>
+<dd>Returns the <a title="pydermonkey.Runtime" class="reference" href="#pydermonkey.Runtime"><tt class="xref docutils literal"><span class="pre">Runtime</span></tt></a> that the context belongs to.</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.get_stack">
+<tt class="descname">get_stack</tt><big>(</big><big>)</big><a class="headerlink" href="#pydermonkey.Context.get_stack" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns a dictionary containing information about the context&#8217;s
+current stack.</p>
+<p>The dictionary contains the following string keys:</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="45%" />
+<col width="55%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">key</th>
+<th class="head">value</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td><tt class="xref docutils literal"><span class="pre">script</span></tt></td>
+<td><a title="pydermonkey.Script" class="reference" href="#pydermonkey.Script"><tt class="xref docutils literal"><span class="pre">Script</span></tt></a> of the frame.
+This may be <tt class="xref docutils literal"><span class="pre">None</span></tt> if the frame
+isn&#8217;t a scripted frame, or if it&#8217;s
+not possible to expose the script
+to Python for some reason.</td>
+</tr>
+<tr><td><tt class="xref docutils literal"><span class="pre">lineno</span></tt></td>
+<td>Line number of the frame, if the
+frame is scripted.</td>
+</tr>
+<tr><td><tt class="xref docutils literal"><span class="pre">pc</span></tt></td>
+<td>Program counter of the frame; this
+is an index into the bytecode of
+the frame&#8217;s script, if the frame
+is scripted.</td>
+</tr>
+<tr><td><tt class="xref docutils literal"><span class="pre">function</span></tt></td>
+<td>The <a title="pydermonkey.Function" class="reference" href="#pydermonkey.Function"><tt class="xref docutils literal"><span class="pre">Function</span></tt></a> in which the
+frame is executing, if any.</td>
+</tr>
+<tr><td><tt class="xref docutils literal"><span class="pre">caller</span></tt></td>
+<td>Dictionary containing information
+about the stack frame of the
+caller of this frame. If this frame
+has no caller, this value is
+<tt class="xref docutils literal"><span class="pre">None</span></tt>.</td>
+</tr>
+</tbody>
+</table>
+<p>If the context isn&#8217;t currently executing any code (i.e., the stack
+is empty), this method returns <tt class="xref docutils literal"><span class="pre">None</span></tt>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.new_object">
+<tt class="descname">new_object</tt><big>(</big><span class="optional">[</span><em>private_obj</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#pydermonkey.Context.new_object" title="Permalink to this definition">¶</a></dt>
+<dd>Creates a new <a title="pydermonkey.Object" class="reference" href="#pydermonkey.Object"><tt class="xref docutils literal"><span class="pre">Object</span></tt></a> instance and returns
+it. <tt class="docutils literal"><span class="pre">private_obj</span></tt> is any Python object that is privately
+stored within the new JS object; it can be retrieved using
+<a title="pydermonkey.Context.get_object_private" class="reference" href="#pydermonkey.Context.get_object_private"><tt class="xref docutils literal"><span class="pre">get_object_private()</span></tt></a>.</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.new_function">
+<tt class="descname">new_function</tt><big>(</big><em>func</em>, <em>name</em><big>)</big><a class="headerlink" href="#pydermonkey.Context.new_function" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates a new <a title="pydermonkey.Function" class="reference" href="#pydermonkey.Function"><tt class="xref docutils literal"><span class="pre">Function</span></tt></a> instance that wraps the
+given Python callable.  In JS-land, the function will
+have the given name.</p>
+<p>When the function is executed from JavaScript, <cite>func</cite>
+will be passed three positional arguments.</p>
+<p>The first argument is a <a title="pydermonkey.Context" class="reference" href="#pydermonkey.Context"><tt class="xref docutils literal"><span class="pre">Context</span></tt></a> that represents the
+JS context which is calling the function.</p>
+<p>The second argument is an <a title="pydermonkey.Object" class="reference" href="#pydermonkey.Object"><tt class="xref docutils literal"><span class="pre">Object</span></tt></a> that represents the
+value of <tt class="docutils literal"><span class="pre">this</span></tt> for the duration of the call.</p>
+<p>The third argument is a tuple containing the arguments
+passed to the function.</p>
+<p>For instance:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">cx</span><span class="p">,</span> <span class="n">this</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
+<span class="gp">... </span>  <span class="k">return</span> <span class="n">args</span><span class="p">[</span><span class="mf">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">args</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">define_property</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">&#39;add&#39;</span><span class="p">,</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_function</span><span class="p">(</span><span class="n">add</span><span class="p">,</span> <span class="s">&#39;add&#39;</span><span class="p">))</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">evaluate_script</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">&#39;add(1, 1);&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
+<span class="go">2</span>
+</pre></div>
+</div>
+</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.define_property">
+<tt class="descname">define_property</tt><big>(</big><em>object</em>, <em>name</em>, <em>value</em><big>)</big><a class="headerlink" href="#pydermonkey.Context.define_property" title="Permalink to this definition">¶</a></dt>
+<dd>Creates a new property on <cite>object</cite>, bypassing any JavaScript setters.</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.has_property">
+<tt class="descname">has_property</tt><big>(</big><em>object</em>, <em>name</em><big>)</big><a class="headerlink" href="#pydermonkey.Context.has_property" title="Permalink to this definition">¶</a></dt>
+<dd>Returns whether or not <cite>object</cite> has the specified property.</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.get_property">
+<tt class="descname">get_property</tt><big>(</big><em>object</em>, <em>name</em><big>)</big><a class="headerlink" href="#pydermonkey.Context.get_property" title="Permalink to this definition">¶</a></dt>
+<dd><p>Finds the specified property on <cite>object</cite> and returns its value,
+possibly invoking a JavaScript getter.</p>
+<p>Example:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">define_property</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">&#39;beets&#39;</span><span class="p">,</span> <span class="s">&#39;i like beets.&#39;</span><span class="p">)</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">get_property</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">&#39;beets&#39;</span><span class="p">)</span>
+<span class="go">u&#39;i like beets.&#39;</span>
+</pre></div>
+</div>
+<p>Note also that calling this function on undefined properties
+yields <a title="pydermonkey.undefined" class="reference" href="#pydermonkey.undefined"><tt class="xref docutils literal"><span class="pre">undefined</span></tt></a>:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">get_property</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">&#39;carrots&#39;</span><span class="p">)</span>
+<span class="go">pydermonkey.undefined</span>
+</pre></div>
+</div>
+</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.get_object_private">
+<tt class="descname">get_object_private</tt><big>(</big><em>object</em><big>)</big><a class="headerlink" href="#pydermonkey.Context.get_object_private" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns the <tt class="docutils literal"><span class="pre">private_obj</span></tt> passed to <a title="pydermonkey.Context.new_object" class="reference" href="#pydermonkey.Context.new_object"><tt class="xref docutils literal"><span class="pre">new_object()</span></tt></a>
+when <cite>object</cite> was first created. If it doesn&#8217;t exist, <tt class="xref docutils literal"><span class="pre">None</span></tt>
+is returned.</p>
+<p>If <cite>object</cite> was created with <a title="pydermonkey.Context.new_function" class="reference" href="#pydermonkey.Context.new_function"><tt class="xref docutils literal"><span class="pre">new_function()</span></tt></a>, then this
+method returns the Python callable wrapped by <cite>object</cite>.</p>
+<p>This functionality is useful if you want to securely represent
+Python objects in JS-land.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.clear_object_private">
+<tt class="descname">clear_object_private</tt><big>(</big><em>object</em><big>)</big><a class="headerlink" href="#pydermonkey.Context.clear_object_private" title="Permalink to this definition">¶</a></dt>
+<dd><p>Clears the <tt class="docutils literal"><span class="pre">private_obj</span></tt> passed to <a title="pydermonkey.Context.new_object" class="reference" href="#pydermonkey.Context.new_object"><tt class="xref docutils literal"><span class="pre">new_object()</span></tt></a>
+when <cite>object</cite> was first created. If it doesn&#8217;t exist, this
+function returns nothing.</p>
+<p>If <cite>object</cite> was created with <a title="pydermonkey.Context.new_function" class="reference" href="#pydermonkey.Context.new_function"><tt class="xref docutils literal"><span class="pre">new_function()</span></tt></a>, then this
+method effectively &#8220;unbinds&#8221; the Python callable wrapped by
+<cite>object</cite>. If <cite>object</cite> is later called, an exception will be
+raised.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.evaluate_script">
+<tt class="descname">evaluate_script</tt><big>(</big><em>globalobj</em>, <em>code</em>, <em>filename</em>, <em>lineno</em><big>)</big><a class="headerlink" href="#pydermonkey.Context.evaluate_script" title="Permalink to this definition">¶</a></dt>
+<dd><p>Evaluates the text <cite>code</cite> using <cite>globalobj</cite> as the global
+object/scope.</p>
+<p>It&#8217;s assumed that <cite>code</cite> is coming from the file named by <cite>filename</cite>;
+the first line of <cite>code</cite> is assumed to be line number <cite>lineno</cite> of
+<cite>filename</cite>. This metadata is very useful for debugging stack traces,
+exceptions, and so forth.</p>
+<p>For example:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">init_standard_classes</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">evaluate_script</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">&#39;5 * Math&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
+<span class="go">nan</span>
+</pre></div>
+</div>
+</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.compile_script">
+<tt class="descname">compile_script</tt><big>(</big><em>code</em>, <em>filename</em>, <em>lineno</em><big>)</big><a class="headerlink" href="#pydermonkey.Context.compile_script" title="Permalink to this definition">¶</a></dt>
+<dd><p>Compiles the given string of code and returns a <a title="pydermonkey.Script" class="reference" href="#pydermonkey.Script"><tt class="xref docutils literal"><span class="pre">Script</span></tt></a>
+instance that can be executed via <a title="pydermonkey.Context.execute_script" class="reference" href="#pydermonkey.Context.execute_script"><tt class="xref docutils literal"><span class="pre">execute_script()</span></tt></a>.</p>
+<p><cite>filename</cite> and <cite>lineno</cite> are used just as in
+<a title="pydermonkey.Context.evaluate_script" class="reference" href="#pydermonkey.Context.evaluate_script"><tt class="xref docutils literal"><span class="pre">evaluate_script()</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.execute_script">
+<tt class="descname">execute_script</tt><big>(</big><em>globalobj</em>, <em>script</em><big>)</big><a class="headerlink" href="#pydermonkey.Context.execute_script" title="Permalink to this definition">¶</a></dt>
+<dd><p>Executes the code in the given <a title="pydermonkey.Script" class="reference" href="#pydermonkey.Script"><tt class="xref docutils literal"><span class="pre">Script</span></tt></a> object, using
+<cite>globalobj</cite> as the global object/scope, and returns the result.</p>
+<p>For example:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">init_standard_classes</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">script</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">compile_script</span><span class="p">(</span><span class="s">&#39;5 * Math&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">execute_script</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">script</span><span class="p">)</span>
+<span class="go">nan</span>
+</pre></div>
+</div>
+</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.call_function">
+<tt class="descname">call_function</tt><big>(</big><em>thisobj</em>, <em>func</em>, <em>args</em><big>)</big><a class="headerlink" href="#pydermonkey.Context.call_function" title="Permalink to this definition">¶</a></dt>
+<dd><p>Calls a JavaScript function.</p>
+<p><cite>thisobj</cite> is an <a title="pydermonkey.Object" class="reference" href="#pydermonkey.Object"><tt class="xref docutils literal"><span class="pre">Object</span></tt></a> that will be used as the value
+of <tt class="docutils literal"><span class="pre">this</span></tt> when the function executes, <cite>func</cite> is the
+<a title="pydermonkey.Function" class="reference" href="#pydermonkey.Function"><tt class="xref docutils literal"><span class="pre">Function</span></tt></a> to execute, and <cite>args</cite> is a tuple of arguments
+to pass to the function.</p>
+<p>For instance:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">init_standard_classes</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">Math</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">get_property</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">&#39;Math&#39;</span><span class="p">)</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">floor</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">get_property</span><span class="p">(</span><span class="n">Math</span><span class="p">,</span> <span class="s">&#39;floor&#39;</span><span class="p">)</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">call_function</span><span class="p">(</span><span class="n">Math</span><span class="p">,</span> <span class="n">floor</span><span class="p">,</span> <span class="p">(</span><span class="mf">5.3</span><span class="p">,))</span>
+<span class="go">5</span>
+</pre></div>
+</div>
+</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.init_standard_classes">
+<tt class="descname">init_standard_classes</tt><big>(</big><em>object</em><big>)</big><a class="headerlink" href="#pydermonkey.Context.init_standard_classes" title="Permalink to this definition">¶</a></dt>
+<dd>Defines the standard JavaScript classes on the given
+<a title="pydermonkey.Object" class="reference" href="#pydermonkey.Object"><tt class="xref docutils literal"><span class="pre">Object</span></tt></a>, such as <tt class="docutils literal"><span class="pre">Array</span></tt>, <tt class="docutils literal"><span class="pre">eval</span></tt>, <tt class="docutils literal"><span class="pre">undefined</span></tt>, and
+so forth. For more information, see the documentation to
+<a class="reference" href="https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_InitStandardClasses">JS_InitStandardClasses()</a>,
+which this method wraps.</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.gc">
+<tt class="descname">gc</tt><big>(</big><big>)</big><a class="headerlink" href="#pydermonkey.Context.gc" title="Permalink to this definition">¶</a></dt>
+<dd>Performs garbage collection on the context&#8217;s JavaScript runtime.</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.is_exception_pending">
+<tt class="descname">is_exception_pending</tt><big>(</big><big>)</big><a class="headerlink" href="#pydermonkey.Context.is_exception_pending" title="Permalink to this definition">¶</a></dt>
+<dd>Returns whether an exception is currently being propagated in
+the context.</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.get_pending_exception">
+<tt class="descname">get_pending_exception</tt><big>(</big><big>)</big><a class="headerlink" href="#pydermonkey.Context.get_pending_exception" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns the current exception being propagated in the context. If
+no exception is being propagated, this method returns <tt class="xref docutils literal"><span class="pre">None</span></tt>.</p>
+<p>If you need to disambiguate between whether <tt class="xref docutils literal"><span class="pre">None</span></tt> is the
+pending exception or there is no pending exception, use
+<a title="pydermonkey.Context.is_exception_pending" class="reference" href="#pydermonkey.Context.is_exception_pending"><tt class="xref docutils literal"><span class="pre">is_exception_pending()</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.set_throw_hook">
+<tt class="descname">set_throw_hook</tt><big>(</big><em>func</em><big>)</big><a class="headerlink" href="#pydermonkey.Context.set_throw_hook" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets the throw hook for the context to the given Python callable.
+The hook is triggered whenever an exception is thrown in the
+context.</p>
+<p><cite>func</cite> takes one argument: the context that triggered it.</p>
+<p>For example, here&#8217;s a throw hook that prints information about
+an exception as it&#8217;s being propagated through the stack:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">throwhook</span><span class="p">(</span><span class="n">cx</span><span class="p">):</span>
+<span class="gp">... </span>  <span class="n">stack</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">get_stack</span><span class="p">()</span>
+<span class="gp">... </span>  <span class="k">if</span> <span class="n">stack</span><span class="p">[</span><span class="s">&#39;function&#39;</span><span class="p">]:</span>
+<span class="gp">... </span>    <span class="n">where</span> <span class="o">=</span> <span class="n">stack</span><span class="p">[</span><span class="s">&#39;function&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">name</span>
+<span class="gp">... </span>  <span class="k">else</span><span class="p">:</span>
+<span class="gp">... </span>    <span class="n">where</span> <span class="o">=</span> <span class="n">stack</span><span class="p">[</span><span class="s">&#39;script&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">filename</span>
+<span class="gp">... </span>  <span class="n">exc</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">get_pending_exception</span><span class="p">()</span>
+<span class="gp">... </span>  <span class="k">print</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s"> being thrown in </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">exc</span><span class="p">,</span> <span class="n">where</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>Here&#8217;s the hook in action:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">set_throw_hook</span><span class="p">(</span><span class="n">throwhook</span><span class="p">)</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">code</span> <span class="o">=</span> <span class="s">&quot;(function foo() { throw &#39;oops&#39; })()&quot;</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
+<span class="gp">... </span>  <span class="n">cx</span><span class="o">.</span><span class="n">evaluate_script</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
+<span class="gp">... </span><span class="k">except</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span>
+<span class="gp">... </span>  <span class="k">print</span> <span class="s">&quot;caught </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">e</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="mf">0</span><span class="p">]</span>
+<span class="go">oops being thrown in foo</span>
+<span class="go">oops being thrown in &lt;string&gt;</span>
+<span class="go">caught oops</span>
+</pre></div>
+</div>
+</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.set_operation_callback">
+<tt class="descname">set_operation_callback</tt><big>(</big><em>func</em><big>)</big><a class="headerlink" href="#pydermonkey.Context.set_operation_callback" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets the operation callback for the context to the given Python
+callable. The callback can be triggered via
+<a title="pydermonkey.Context.trigger_operation_callback" class="reference" href="#pydermonkey.Context.trigger_operation_callback"><tt class="xref docutils literal"><span class="pre">trigger_operation_callback()</span></tt></a>.</p>
+<p><cite>func</cite> takes one argument: the context that triggered it.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="pydermonkey.Context.trigger_operation_callback">
+<tt class="descname">trigger_operation_callback</tt><big>(</big><big>)</big><a class="headerlink" href="#pydermonkey.Context.trigger_operation_callback" title="Permalink to this definition">¶</a></dt>
+<dd><p>Triggers the context&#8217;s operation callback. If no callback has
+yet been set, this function does nothing.</p>
+<p>This function is one of the few thread-safe functions available
+to a JS runtime, and together with
+<a title="pydermonkey.Context.set_operation_callback" class="reference" href="#pydermonkey.Context.set_operation_callback"><tt class="xref docutils literal"><span class="pre">set_operation_callback()</span></tt></a> can be used to abort the
+execution of long-running code.</p>
+<p>For instance, we first create an operation callback to stop
+long-running code by throwing an exception:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">import</span> <span class="nn">time</span><span class="o">,</span> <span class="nn">threading</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">stop_running_code</span><span class="p">(</span><span class="n">cx</span><span class="p">):</span>
+<span class="gp">... </span>  <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s">&#39;JS took too long to execute.&#39;</span><span class="p">)</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">set_operation_callback</span><span class="p">(</span><span class="n">stop_running_code</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>Then we create a watchdog thread to trigger the operation
+callback once a long amount of time has passed:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">watchdog_thread</span><span class="p">():</span>
+<span class="gp">... </span>  <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span>                 <span class="c"># An eternity to a computer!</span>
+<span class="gp">... </span>  <span class="n">cx</span><span class="o">.</span><span class="n">trigger_operation_callback</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">watchdog_thread</span><span class="p">)</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>Now, when we execute code that takes too long to run, it gets
+aborted:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
+<span class="gp">... </span>  <span class="n">cx</span><span class="o">.</span><span class="n">evaluate_script</span><span class="p">(</span><span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">(),</span> <span class="s">&#39;while (1) {}&#39;</span><span class="p">,</span>
+<span class="gp">... </span>                     <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
+<span class="gp">... </span><span class="k">except</span> <span class="n">pydermonkey</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span>
+<span class="gp">... </span>  <span class="k">print</span> <span class="n">cx</span><span class="o">.</span><span class="n">get_object_private</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="mf">0</span><span class="p">])</span>
+<span class="go">JS took too long to execute.</span>
+</pre></div>
+</div>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="pydermonkey.Runtime">
+<em class="property">
+class </em><tt class="descclassname">pydermonkey.</tt><tt class="descname">Runtime</tt><a class="headerlink" href="#pydermonkey.Runtime" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates a new JavaScript runtime. JS objects created by the runtime
+may only interact with other JS objects of the same runtime.</p>
+<p>With few exceptions, objects belonging to a runtime can currently
+only be used in the same thread that the runtime was created
+in. This may be changed in the future, since SpiderMonkey itself
+has support for thread safety.</p>
+<p>JS runtimes are weak-referencable.</p>
+<dl class="method">
+<dt id="pydermonkey.Runtime.new_context">
+<tt class="descname">new_context</tt><big>(</big><big>)</big><a class="headerlink" href="#pydermonkey.Runtime.new_context" title="Permalink to this definition">¶</a></dt>
+<dd>Creates a new Context object and returns it. Contexts are best
+conceptualized as threads of execution in a JS runtme; each one
+has a program counter, a current exception state, and so
+forth. JS objects may be freely accessed and changed by contexts
+that are associated with the same JS runtime as the objects.</dd></dl>
+
+</dd></dl>
+
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+            <h4>Previous topic</h4>
+            <p class="topless"><a href="index.html"
+                                  title="previous chapter">Pydermonkey Documentation</a></p>
+            <h3>This Page</h3>
+            <ul class="this-page-menu">
+              <li><a href="_sources/pydermonkey.txt"
+                     rel="nofollow">Show Source</a></li>
+            </ul>
+          <div id="searchbox" style="display: none">
+            <h3>Quick search</h3>
+              <form class="search" action="search.html" method="get">
+                <input type="text" name="q" size="18" />
+                <input type="submit" value="Go" />
+                <input type="hidden" name="check_keywords" value="yes" />
+                <input type="hidden" name="area" value="default" />
+              </form>
+              <p class="searchtip" style="font-size: 90%">
+              Enter search terms or a module, class or function name.
+              </p>
+          </div>
+          <script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="modindex.html" title="Global Module Index"
+             >modules</a> |</li>
+        <li class="right" >
+          <a href="index.html" title="Pydermonkey Documentation"
+             >previous</a> |</li>
+        <li><a href="index.html">Pydermonkey v0.0.1 documentation</a> &raquo;</li> 
+      </ul>
+    </div>
+    <div class="footer">
+      &copy; Copyright 2009, Atul Varma.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.2.
+    </div>
+  </body>
+</html>
\ No newline at end of file
--- a/docs/rendered/pymonkey.html	Sun Aug 30 20:56:43 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,593 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    
-    <title>pymonkey — Access SpiderMonkey from Python &mdash; Pymonkey v0.0.1 documentation</title>
-    <link rel="stylesheet" href="_static/default.css" type="text/css" />
-    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
-    <script type="text/javascript">
-      var DOCUMENTATION_OPTIONS = {
-        URL_ROOT:    '',
-        VERSION:     '0.0.1',
-        COLLAPSE_MODINDEX: false,
-        FILE_SUFFIX: '.html',
-        HAS_SOURCE:  true
-      };
-    </script>
-    <script type="text/javascript" src="_static/jquery.js"></script>
-    <script type="text/javascript" src="_static/doctools.js"></script>
-    <link rel="top" title="Pymonkey v0.0.1 documentation" href="index.html" />
-    <link rel="prev" title="Pymonkey Documentation" href="index.html" /> 
-  </head>
-  <body>
-    <div class="related">
-      <h3>Navigation</h3>
-      <ul>
-        <li class="right" style="margin-right: 10px">
-          <a href="genindex.html" title="General Index"
-             accesskey="I">index</a></li>
-        <li class="right" >
-          <a href="modindex.html" title="Global Module Index"
-             accesskey="M">modules</a> |</li>
-        <li class="right" >
-          <a href="index.html" title="Pymonkey Documentation"
-             accesskey="P">previous</a> |</li>
-        <li><a href="index.html">Pymonkey v0.0.1 documentation</a> &raquo;</li> 
-      </ul>
-    </div>  
-
-    <div class="document">
-      <div class="documentwrapper">
-        <div class="bodywrapper">
-          <div class="body">
-            
-  <div class="section" id="module-pymonkey">
-<h1><tt class="xref docutils literal"><span class="pre">pymonkey</span></tt> &#8212; Access SpiderMonkey from Python<a class="headerlink" href="#module-pymonkey" title="Permalink to this headline">¶</a></h1>
-<p>This module offers a low-level interface to the <a class="reference" href="https://developer.mozilla.org/en/SpiderMonkey">Mozilla SpiderMonkey</a> JavaScript engine.</p>
-<dl class="exception">
-<dt id="pymonkey.error">
-<em class="property">
-exception </em><tt class="descclassname">pymonkey.</tt><tt class="descname">error</tt><a class="headerlink" href="#pymonkey.error" title="Permalink to this definition">¶</a></dt>
-<dd><p>This is the type of any SpiderMonkey-related errors thrown by this
-module.</p>
-<p>If the error is a wrapped JavaScript exception, the first argument
-will be the thrown JS exception, and the second argument will be
-the JS exception converted to a string. Otherwise, the error
-will only contain a descriptive string argument.</p>
-<p>For example:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">evaluate_script</span><span class="p">(</span><span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">(),</span> <span class="s">&#39;throw 1&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
-<span class="gp">...</span>
-<span class="go">error: (1, u&#39;1&#39;)</span>
-</pre></div>
-</div>
-</dd></dl>
-
-<dl class="data">
-<dt id="pymonkey.undefined">
-<tt class="descclassname">pymonkey.</tt><tt class="descname">undefined</tt><a class="headerlink" href="#pymonkey.undefined" title="Permalink to this definition">¶</a></dt>
-<dd><p>This is the singleton that represents the JavaScript value
-<tt class="docutils literal"><span class="pre">undefined</span></tt>, as Python has no equivalent representation
-(JavaScript&#8217;s <tt class="docutils literal"><span class="pre">null</span></tt> is mapped to Python&#8217;s <tt class="xref docutils literal"><span class="pre">None</span></tt> object).
-For instance:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">evaluate_script</span><span class="p">(</span><span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">(),</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
-<span class="go">pymonkey.undefined</span>
-</pre></div>
-</div>
-<p>This object also has a &#8220;falsy&#8221; value:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">if</span> <span class="ow">not</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">undefined</span><span class="p">:</span>
-<span class="gp">... </span>  <span class="k">print</span> <span class="s">&quot;See, it&#39;s falsy!&quot;</span>
-<span class="go">See, it&#39;s falsy!</span>
-</pre></div>
-</div>
-</dd></dl>
-
-<dl class="class">
-<dt id="pymonkey.Object">
-<em class="property">
-class </em><tt class="descclassname">pymonkey.</tt><tt class="descname">Object</tt><a class="headerlink" href="#pymonkey.Object" title="Permalink to this definition">¶</a></dt>
-<dd><p>This is the type of JavaScript objects. Such objects can only be
-created via Pymonkey calls like <a title="pymonkey.Context.new_object" class="reference" href="#pymonkey.Context.new_object"><tt class="xref docutils literal"><span class="pre">Context.new_object()</span></tt></a> or
-through the execution of JS code, but this type object can be used
-with Python&#8217;s built-in <tt class="xref docutils literal"><span class="pre">isinstance()</span></tt> to verify that an
-object is a JS object, like so:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">Object</span><span class="p">)</span>
-<span class="go">True</span>
-</pre></div>
-</div>
-<p>Note that <a title="pymonkey.Object" class="reference" href="#pymonkey.Object"><tt class="xref docutils literal"><span class="pre">Object</span></tt></a> and all its subclasses are
-identity-preserving when passed between Python and
-JavaScript code. For instance:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">obj1</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">obj2</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">evaluate_script</span><span class="p">(</span><span class="n">obj1</span><span class="p">,</span> <span class="s">&#39;this&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">obj1</span> <span class="ow">is</span> <span class="n">obj2</span>
-<span class="go">True</span>
-</pre></div>
-</div>
-<dl class="method">
-<dt id="pymonkey.Object.get_runtime">
-<tt class="descname">get_runtime</tt><big>(</big><big>)</big><a class="headerlink" href="#pymonkey.Object.get_runtime" title="Permalink to this definition">¶</a></dt>
-<dd>Returns the <a title="pymonkey.Runtime" class="reference" href="#pymonkey.Runtime"><tt class="xref docutils literal"><span class="pre">Runtime</span></tt></a> that the object belongs to.</dd></dl>
-
-</dd></dl>
-
-<dl class="class">
-<dt id="pymonkey.Function">
-<em class="property">
-class </em><tt class="descclassname">pymonkey.</tt><tt class="descname">Function</tt><a class="headerlink" href="#pymonkey.Function" title="Permalink to this definition">¶</a></dt>
-<dd><p>This is the type of JavaScript functions, which is a subtype of
-<a title="pymonkey.Object" class="reference" href="#pymonkey.Object"><tt class="xref docutils literal"><span class="pre">Object</span></tt></a>.</p>
-<dl class="data">
-<dt id="pymonkey.Function.filename">
-<tt class="descname">filename</tt><a class="headerlink" href="#pymonkey.Function.filename" title="Permalink to this definition">¶</a></dt>
-<dd>Name of the file that contains the function&#8217;s original JS source
-code. If the function isn&#8217;t a JS function, this value is
-<tt class="xref docutils literal"><span class="pre">None</span></tt>.</dd></dl>
-
-<dl class="data">
-<dt id="pymonkey.Function.base_lineno">
-<tt class="descname">base_lineno</tt><a class="headerlink" href="#pymonkey.Function.base_lineno" title="Permalink to this definition">¶</a></dt>
-<dd>The line number at which the function&#8217;s JS source code begins.</dd></dl>
-
-<dl class="data">
-<dt id="pymonkey.Function.line_extent">
-<tt class="descname">line_extent</tt><a class="headerlink" href="#pymonkey.Function.line_extent" title="Permalink to this definition">¶</a></dt>
-<dd>The number of lines comprising the function&#8217;s JS source code.</dd></dl>
-
-<dl class="data">
-<dt id="pymonkey.Function.is_python">
-<tt class="descname">is_python</tt><a class="headerlink" href="#pymonkey.Function.is_python" title="Permalink to this definition">¶</a></dt>
-<dd>Whether or not the function is actually implemented in Python.
-If it is, you can use <a title="pymonkey.Context.get_object_private" class="reference" href="#pymonkey.Context.get_object_private"><tt class="xref docutils literal"><span class="pre">Context.get_object_private()</span></tt></a> to
-retrieve this Python function.</dd></dl>
-
-</dd></dl>
-
-<dl class="class">
-<dt id="pymonkey.Script">
-<em class="property">
-class </em><tt class="descclassname">pymonkey.</tt><tt class="descname">Script</tt><a class="headerlink" href="#pymonkey.Script" title="Permalink to this definition">¶</a></dt>
-<dd><p>This is the type of compiled JavaScript scripts; it&#8217;s actually a
-subtype of <a title="pymonkey.Object" class="reference" href="#pymonkey.Object"><tt class="xref docutils literal"><span class="pre">Object</span></tt></a>, though when exposed to JS code it
-doesn&#8217;t provide access to any special data or functionality.</p>
-<p>Script instances have a read-only buffer interface that exposes
-their bytecode. This can be accessed by passing an instance to
-Python&#8217;s built-in <tt class="docutils literal"><span class="pre">buffer()</span></tt> function.</p>
-<dl class="data">
-<dt id="pymonkey.Script.filename">
-<tt class="descname">filename</tt><a class="headerlink" href="#pymonkey.Script.filename" title="Permalink to this definition">¶</a></dt>
-<dd>The filename of the script&#8217;s original source code.</dd></dl>
-
-<dl class="data">
-<dt id="pymonkey.Script.base_lineno">
-<tt class="descname">base_lineno</tt><a class="headerlink" href="#pymonkey.Script.base_lineno" title="Permalink to this definition">¶</a></dt>
-<dd>The line number at which the script&#8217;s original source code
-begins.</dd></dl>
-
-<dl class="data">
-<dt id="pymonkey.Script.line_extent">
-<tt class="descname">line_extent</tt><a class="headerlink" href="#pymonkey.Script.line_extent" title="Permalink to this definition">¶</a></dt>
-<dd>The number of lines comprising the original source code.</dd></dl>
-
-</dd></dl>
-
-<dl class="class">
-<dt id="pymonkey.Context">
-<em class="property">
-class </em><tt class="descclassname">pymonkey.</tt><tt class="descname">Context</tt><a class="headerlink" href="#pymonkey.Context" title="Permalink to this definition">¶</a></dt>
-<dd><p>This is the type of JavaScript context objects. Contexts can only
-be created via a call to <a title="pymonkey.Runtime.new_context" class="reference" href="#pymonkey.Runtime.new_context"><tt class="xref docutils literal"><span class="pre">Runtime.new_context()</span></tt></a>, but this
-type object can be used with Python&#8217;s built-in <tt class="xref docutils literal"><span class="pre">isinstance()</span></tt>
-to verify that an object is a context, like so:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="nb">isinstance</span><span class="p">(</span><span class="n">cx</span><span class="p">,</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">Context</span><span class="p">)</span>
-<span class="go">True</span>
-</pre></div>
-</div>
-<p>JS contexts are weak-referencable.</p>
-<dl class="method">
-<dt id="pymonkey.Context.get_runtime">
-<tt class="descname">get_runtime</tt><big>(</big><big>)</big><a class="headerlink" href="#pymonkey.Context.get_runtime" title="Permalink to this definition">¶</a></dt>
-<dd>Returns the <a title="pymonkey.Runtime" class="reference" href="#pymonkey.Runtime"><tt class="xref docutils literal"><span class="pre">Runtime</span></tt></a> that the context belongs to.</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.get_stack">
-<tt class="descname">get_stack</tt><big>(</big><big>)</big><a class="headerlink" href="#pymonkey.Context.get_stack" title="Permalink to this definition">¶</a></dt>
-<dd><p>Returns a dictionary containing information about the context&#8217;s
-current stack.</p>
-<p>The dictionary contains the following string keys:</p>
-<table border="1" class="docutils">
-<colgroup>
-<col width="45%" />
-<col width="55%" />
-</colgroup>
-<thead valign="bottom">
-<tr><th class="head">key</th>
-<th class="head">value</th>
-</tr>
-</thead>
-<tbody valign="top">
-<tr><td><tt class="xref docutils literal"><span class="pre">script</span></tt></td>
-<td><a title="pymonkey.Script" class="reference" href="#pymonkey.Script"><tt class="xref docutils literal"><span class="pre">Script</span></tt></a> of the frame.
-This may be <tt class="xref docutils literal"><span class="pre">None</span></tt> if the frame
-isn&#8217;t a scripted frame, or if it&#8217;s
-not possible to expose the script
-to Python for some reason.</td>
-</tr>
-<tr><td><tt class="xref docutils literal"><span class="pre">lineno</span></tt></td>
-<td>Line number of the frame, if the
-frame is scripted.</td>
-</tr>
-<tr><td><tt class="xref docutils literal"><span class="pre">pc</span></tt></td>
-<td>Program counter of the frame; this
-is an index into the bytecode of
-the frame&#8217;s script, if the frame
-is scripted.</td>
-</tr>
-<tr><td><tt class="xref docutils literal"><span class="pre">function</span></tt></td>
-<td>The <a title="pymonkey.Function" class="reference" href="#pymonkey.Function"><tt class="xref docutils literal"><span class="pre">Function</span></tt></a> in which the
-frame is executing, if any.</td>
-</tr>
-<tr><td><tt class="xref docutils literal"><span class="pre">caller</span></tt></td>
-<td>Dictionary containing information
-about the stack frame of the
-caller of this frame. If this frame
-has no caller, this value is
-<tt class="xref docutils literal"><span class="pre">None</span></tt>.</td>
-</tr>
-</tbody>
-</table>
-<p>If the context isn&#8217;t currently executing any code (i.e., the stack
-is empty), this method returns <tt class="xref docutils literal"><span class="pre">None</span></tt>.</p>
-</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.new_object">
-<tt class="descname">new_object</tt><big>(</big><span class="optional">[</span><em>private_obj</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#pymonkey.Context.new_object" title="Permalink to this definition">¶</a></dt>
-<dd>Creates a new <a title="pymonkey.Object" class="reference" href="#pymonkey.Object"><tt class="xref docutils literal"><span class="pre">Object</span></tt></a> instance and returns
-it. <tt class="docutils literal"><span class="pre">private_obj</span></tt> is any Python object that is privately
-stored within the new JS object; it can be retrieved using
-<a title="pymonkey.Context.get_object_private" class="reference" href="#pymonkey.Context.get_object_private"><tt class="xref docutils literal"><span class="pre">get_object_private()</span></tt></a>.</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.new_function">
-<tt class="descname">new_function</tt><big>(</big><em>func</em>, <em>name</em><big>)</big><a class="headerlink" href="#pymonkey.Context.new_function" title="Permalink to this definition">¶</a></dt>
-<dd><p>Creates a new <a title="pymonkey.Function" class="reference" href="#pymonkey.Function"><tt class="xref docutils literal"><span class="pre">Function</span></tt></a> instance that wraps the
-given Python callable.  In JS-land, the function will
-have the given name.</p>
-<p>When the function is executed from JavaScript, <cite>func</cite>
-will be passed three positional arguments.</p>
-<p>The first argument is a <a title="pymonkey.Context" class="reference" href="#pymonkey.Context"><tt class="xref docutils literal"><span class="pre">Context</span></tt></a> that represents the
-JS context which is calling the function.</p>
-<p>The second argument is an <a title="pymonkey.Object" class="reference" href="#pymonkey.Object"><tt class="xref docutils literal"><span class="pre">Object</span></tt></a> that represents the
-value of <tt class="docutils literal"><span class="pre">this</span></tt> for the duration of the call.</p>
-<p>The third argument is a tuple containing the arguments
-passed to the function.</p>
-<p>For instance:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">cx</span><span class="p">,</span> <span class="n">this</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
-<span class="gp">... </span>  <span class="k">return</span> <span class="n">args</span><span class="p">[</span><span class="mf">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">args</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">define_property</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">&#39;add&#39;</span><span class="p">,</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_function</span><span class="p">(</span><span class="n">add</span><span class="p">,</span> <span class="s">&#39;add&#39;</span><span class="p">))</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">evaluate_script</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">&#39;add(1, 1);&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
-<span class="go">2</span>
-</pre></div>
-</div>
-</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.define_property">
-<tt class="descname">define_property</tt><big>(</big><em>object</em>, <em>name</em>, <em>value</em><big>)</big><a class="headerlink" href="#pymonkey.Context.define_property" title="Permalink to this definition">¶</a></dt>
-<dd>Creates a new property on <cite>object</cite>, bypassing any JavaScript setters.</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.has_property">
-<tt class="descname">has_property</tt><big>(</big><em>object</em>, <em>name</em><big>)</big><a class="headerlink" href="#pymonkey.Context.has_property" title="Permalink to this definition">¶</a></dt>
-<dd>Returns whether or not <cite>object</cite> has the specified property.</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.get_property">
-<tt class="descname">get_property</tt><big>(</big><em>object</em>, <em>name</em><big>)</big><a class="headerlink" href="#pymonkey.Context.get_property" title="Permalink to this definition">¶</a></dt>
-<dd><p>Finds the specified property on <cite>object</cite> and returns its value,
-possibly invoking a JavaScript getter.</p>
-<p>Example:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">define_property</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">&#39;beets&#39;</span><span class="p">,</span> <span class="s">&#39;i like beets.&#39;</span><span class="p">)</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">get_property</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">&#39;beets&#39;</span><span class="p">)</span>
-<span class="go">u&#39;i like beets.&#39;</span>
-</pre></div>
-</div>
-<p>Note also that calling this function on undefined properties
-yields <a title="pymonkey.undefined" class="reference" href="#pymonkey.undefined"><tt class="xref docutils literal"><span class="pre">undefined</span></tt></a>:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">get_property</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">&#39;carrots&#39;</span><span class="p">)</span>
-<span class="go">pymonkey.undefined</span>
-</pre></div>
-</div>
-</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.get_object_private">
-<tt class="descname">get_object_private</tt><big>(</big><em>object</em><big>)</big><a class="headerlink" href="#pymonkey.Context.get_object_private" title="Permalink to this definition">¶</a></dt>
-<dd><p>Returns the <tt class="docutils literal"><span class="pre">private_obj</span></tt> passed to <a title="pymonkey.Context.new_object" class="reference" href="#pymonkey.Context.new_object"><tt class="xref docutils literal"><span class="pre">new_object()</span></tt></a>
-when <cite>object</cite> was first created. If it doesn&#8217;t exist, <tt class="xref docutils literal"><span class="pre">None</span></tt>
-is returned.</p>
-<p>If <cite>object</cite> was created with <a title="pymonkey.Context.new_function" class="reference" href="#pymonkey.Context.new_function"><tt class="xref docutils literal"><span class="pre">new_function()</span></tt></a>, then this
-method returns the Python callable wrapped by <cite>object</cite>.</p>
-<p>This functionality is useful if you want to securely represent
-Python objects in JS-land.</p>
-</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.clear_object_private">
-<tt class="descname">clear_object_private</tt><big>(</big><em>object</em><big>)</big><a class="headerlink" href="#pymonkey.Context.clear_object_private" title="Permalink to this definition">¶</a></dt>
-<dd><p>Clears the <tt class="docutils literal"><span class="pre">private_obj</span></tt> passed to <a title="pymonkey.Context.new_object" class="reference" href="#pymonkey.Context.new_object"><tt class="xref docutils literal"><span class="pre">new_object()</span></tt></a>
-when <cite>object</cite> was first created. If it doesn&#8217;t exist, this
-function returns nothing.</p>
-<p>If <cite>object</cite> was created with <a title="pymonkey.Context.new_function" class="reference" href="#pymonkey.Context.new_function"><tt class="xref docutils literal"><span class="pre">new_function()</span></tt></a>, then this
-method effectively &#8220;unbinds&#8221; the Python callable wrapped by
-<cite>object</cite>. If <cite>object</cite> is later called, an exception will be
-raised.</p>
-</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.evaluate_script">
-<tt class="descname">evaluate_script</tt><big>(</big><em>globalobj</em>, <em>code</em>, <em>filename</em>, <em>lineno</em><big>)</big><a class="headerlink" href="#pymonkey.Context.evaluate_script" title="Permalink to this definition">¶</a></dt>
-<dd><p>Evaluates the text <cite>code</cite> using <cite>globalobj</cite> as the global
-object/scope.</p>
-<p>It&#8217;s assumed that <cite>code</cite> is coming from the file named by <cite>filename</cite>;
-the first line of <cite>code</cite> is assumed to be line number <cite>lineno</cite> of
-<cite>filename</cite>. This metadata is very useful for debugging stack traces,
-exceptions, and so forth.</p>
-<p>For example:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">init_standard_classes</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">evaluate_script</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">&#39;5 * Math&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
-<span class="go">nan</span>
-</pre></div>
-</div>
-</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.compile_script">
-<tt class="descname">compile_script</tt><big>(</big><em>code</em>, <em>filename</em>, <em>lineno</em><big>)</big><a class="headerlink" href="#pymonkey.Context.compile_script" title="Permalink to this definition">¶</a></dt>
-<dd><p>Compiles the given string of code and returns a <a title="pymonkey.Script" class="reference" href="#pymonkey.Script"><tt class="xref docutils literal"><span class="pre">Script</span></tt></a>
-instance that can be executed via <a title="pymonkey.Context.execute_script" class="reference" href="#pymonkey.Context.execute_script"><tt class="xref docutils literal"><span class="pre">execute_script()</span></tt></a>.</p>
-<p><cite>filename</cite> and <cite>lineno</cite> are used just as in
-<a title="pymonkey.Context.evaluate_script" class="reference" href="#pymonkey.Context.evaluate_script"><tt class="xref docutils literal"><span class="pre">evaluate_script()</span></tt></a>.</p>
-</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.execute_script">
-<tt class="descname">execute_script</tt><big>(</big><em>globalobj</em>, <em>script</em><big>)</big><a class="headerlink" href="#pymonkey.Context.execute_script" title="Permalink to this definition">¶</a></dt>
-<dd><p>Executes the code in the given <a title="pymonkey.Script" class="reference" href="#pymonkey.Script"><tt class="xref docutils literal"><span class="pre">Script</span></tt></a> object, using
-<cite>globalobj</cite> as the global object/scope, and returns the result.</p>
-<p>For example:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">init_standard_classes</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">script</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">compile_script</span><span class="p">(</span><span class="s">&#39;5 * Math&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">execute_script</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">script</span><span class="p">)</span>
-<span class="go">nan</span>
-</pre></div>
-</div>
-</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.call_function">
-<tt class="descname">call_function</tt><big>(</big><em>thisobj</em>, <em>func</em>, <em>args</em><big>)</big><a class="headerlink" href="#pymonkey.Context.call_function" title="Permalink to this definition">¶</a></dt>
-<dd><p>Calls a JavaScript function.</p>
-<p><cite>thisobj</cite> is an <a title="pymonkey.Object" class="reference" href="#pymonkey.Object"><tt class="xref docutils literal"><span class="pre">Object</span></tt></a> that will be used as the value
-of <tt class="docutils literal"><span class="pre">this</span></tt> when the function executes, <cite>func</cite> is the
-<a title="pymonkey.Function" class="reference" href="#pymonkey.Function"><tt class="xref docutils literal"><span class="pre">Function</span></tt></a> to execute, and <cite>args</cite> is a tuple of arguments
-to pass to the function.</p>
-<p>For instance:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">init_standard_classes</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">Math</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">get_property</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">&#39;Math&#39;</span><span class="p">)</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">floor</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">get_property</span><span class="p">(</span><span class="n">Math</span><span class="p">,</span> <span class="s">&#39;floor&#39;</span><span class="p">)</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">call_function</span><span class="p">(</span><span class="n">Math</span><span class="p">,</span> <span class="n">floor</span><span class="p">,</span> <span class="p">(</span><span class="mf">5.3</span><span class="p">,))</span>
-<span class="go">5</span>
-</pre></div>
-</div>
-</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.init_standard_classes">
-<tt class="descname">init_standard_classes</tt><big>(</big><em>object</em><big>)</big><a class="headerlink" href="#pymonkey.Context.init_standard_classes" title="Permalink to this definition">¶</a></dt>
-<dd>Defines the standard JavaScript classes on the given
-<a title="pymonkey.Object" class="reference" href="#pymonkey.Object"><tt class="xref docutils literal"><span class="pre">Object</span></tt></a>, such as <tt class="docutils literal"><span class="pre">Array</span></tt>, <tt class="docutils literal"><span class="pre">eval</span></tt>, <tt class="docutils literal"><span class="pre">undefined</span></tt>, and
-so forth. For more information, see the documentation to
-<a class="reference" href="https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_InitStandardClasses">JS_InitStandardClasses()</a>,
-which this method wraps.</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.gc">
-<tt class="descname">gc</tt><big>(</big><big>)</big><a class="headerlink" href="#pymonkey.Context.gc" title="Permalink to this definition">¶</a></dt>
-<dd>Performs garbage collection on the context&#8217;s JavaScript runtime.</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.is_exception_pending">
-<tt class="descname">is_exception_pending</tt><big>(</big><big>)</big><a class="headerlink" href="#pymonkey.Context.is_exception_pending" title="Permalink to this definition">¶</a></dt>
-<dd>Returns whether an exception is currently being propagated in
-the context.</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.get_pending_exception">
-<tt class="descname">get_pending_exception</tt><big>(</big><big>)</big><a class="headerlink" href="#pymonkey.Context.get_pending_exception" title="Permalink to this definition">¶</a></dt>
-<dd><p>Returns the current exception being propagated in the context. If
-no exception is being propagated, this method returns <tt class="xref docutils literal"><span class="pre">None</span></tt>.</p>
-<p>If you need to disambiguate between whether <tt class="xref docutils literal"><span class="pre">None</span></tt> is the
-pending exception or there is no pending exception, use
-<a title="pymonkey.Context.is_exception_pending" class="reference" href="#pymonkey.Context.is_exception_pending"><tt class="xref docutils literal"><span class="pre">is_exception_pending()</span></tt></a>.</p>
-</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.set_throw_hook">
-<tt class="descname">set_throw_hook</tt><big>(</big><em>func</em><big>)</big><a class="headerlink" href="#pymonkey.Context.set_throw_hook" title="Permalink to this definition">¶</a></dt>
-<dd><p>Sets the throw hook for the context to the given Python callable.
-The hook is triggered whenever an exception is thrown in the
-context.</p>
-<p><cite>func</cite> takes one argument: the context that triggered it.</p>
-<p>For example, here&#8217;s a throw hook that prints information about
-an exception as it&#8217;s being propagated through the stack:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">throwhook</span><span class="p">(</span><span class="n">cx</span><span class="p">):</span>
-<span class="gp">... </span>  <span class="n">stack</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">get_stack</span><span class="p">()</span>
-<span class="gp">... </span>  <span class="k">if</span> <span class="n">stack</span><span class="p">[</span><span class="s">&#39;function&#39;</span><span class="p">]:</span>
-<span class="gp">... </span>    <span class="n">where</span> <span class="o">=</span> <span class="n">stack</span><span class="p">[</span><span class="s">&#39;function&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">name</span>
-<span class="gp">... </span>  <span class="k">else</span><span class="p">:</span>
-<span class="gp">... </span>    <span class="n">where</span> <span class="o">=</span> <span class="n">stack</span><span class="p">[</span><span class="s">&#39;script&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">filename</span>
-<span class="gp">... </span>  <span class="n">exc</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">get_pending_exception</span><span class="p">()</span>
-<span class="gp">... </span>  <span class="k">print</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s"> being thrown in </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">exc</span><span class="p">,</span> <span class="n">where</span><span class="p">)</span>
-</pre></div>
-</div>
-<p>Here&#8217;s the hook in action:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">set_throw_hook</span><span class="p">(</span><span class="n">throwhook</span><span class="p">)</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">code</span> <span class="o">=</span> <span class="s">&quot;(function foo() { throw &#39;oops&#39; })()&quot;</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
-<span class="gp">... </span>  <span class="n">cx</span><span class="o">.</span><span class="n">evaluate_script</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
-<span class="gp">... </span><span class="k">except</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span>
-<span class="gp">... </span>  <span class="k">print</span> <span class="s">&quot;caught </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">e</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="mf">0</span><span class="p">]</span>
-<span class="go">oops being thrown in foo</span>
-<span class="go">oops being thrown in &lt;string&gt;</span>
-<span class="go">caught oops</span>
-</pre></div>
-</div>
-</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.set_operation_callback">
-<tt class="descname">set_operation_callback</tt><big>(</big><em>func</em><big>)</big><a class="headerlink" href="#pymonkey.Context.set_operation_callback" title="Permalink to this definition">¶</a></dt>
-<dd><p>Sets the operation callback for the context to the given Python
-callable. The callback can be triggered via
-<a title="pymonkey.Context.trigger_operation_callback" class="reference" href="#pymonkey.Context.trigger_operation_callback"><tt class="xref docutils literal"><span class="pre">trigger_operation_callback()</span></tt></a>.</p>
-<p><cite>func</cite> takes one argument: the context that triggered it.</p>
-</dd></dl>
-
-<dl class="method">
-<dt id="pymonkey.Context.trigger_operation_callback">
-<tt class="descname">trigger_operation_callback</tt><big>(</big><big>)</big><a class="headerlink" href="#pymonkey.Context.trigger_operation_callback" title="Permalink to this definition">¶</a></dt>
-<dd><p>Triggers the context&#8217;s operation callback. If no callback has
-yet been set, this function does nothing.</p>
-<p>This function is one of the few thread-safe functions available
-to a JS runtime, and together with
-<a title="pymonkey.Context.set_operation_callback" class="reference" href="#pymonkey.Context.set_operation_callback"><tt class="xref docutils literal"><span class="pre">set_operation_callback()</span></tt></a> can be used to abort the
-execution of long-running code.</p>
-<p>For instance, we first create an operation callback to stop
-long-running code by throwing an exception:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">import</span> <span class="nn">time</span><span class="o">,</span> <span class="nn">threading</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span> <span class="o">=</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">Runtime</span><span class="p">()</span><span class="o">.</span><span class="n">new_context</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">stop_running_code</span><span class="p">(</span><span class="n">cx</span><span class="p">):</span>
-<span class="gp">... </span>  <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s">&#39;JS took too long to execute.&#39;</span><span class="p">)</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">cx</span><span class="o">.</span><span class="n">set_operation_callback</span><span class="p">(</span><span class="n">stop_running_code</span><span class="p">)</span>
-</pre></div>
-</div>
-<p>Then we create a watchdog thread to trigger the operation
-callback once a long amount of time has passed:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">watchdog_thread</span><span class="p">():</span>
-<span class="gp">... </span>  <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span>                 <span class="c"># An eternity to a computer!</span>
-<span class="gp">... </span>  <span class="n">cx</span><span class="o">.</span><span class="n">trigger_operation_callback</span><span class="p">()</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">watchdog_thread</span><span class="p">)</span>
-<span class="gp">&gt;&gt;&gt; </span><span class="n">thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
-</pre></div>
-</div>
-<p>Now, when we execute code that takes too long to run, it gets
-aborted:</p>
-<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
-<span class="gp">... </span>  <span class="n">cx</span><span class="o">.</span><span class="n">evaluate_script</span><span class="p">(</span><span class="n">cx</span><span class="o">.</span><span class="n">new_object</span><span class="p">(),</span> <span class="s">&#39;while (1) {}&#39;</span><span class="p">,</span>
-<span class="gp">... </span>                     <span class="s">&#39;&lt;string&gt;&#39;</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
-<span class="gp">... </span><span class="k">except</span> <span class="n">pymonkey</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span>
-<span class="gp">... </span>  <span class="k">print</span> <span class="n">cx</span><span class="o">.</span><span class="n">get_object_private</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="mf">0</span><span class="p">])</span>
-<span class="go">JS took too long to execute.</span>
-</pre></div>
-</div>
-</dd></dl>
-
-</dd></dl>
-
-<dl class="class">
-<dt id="pymonkey.Runtime">
-<em class="property">
-class </em><tt class="descclassname">pymonkey.</tt><tt class="descname">Runtime</tt><a class="headerlink" href="#pymonkey.Runtime" title="Permalink to this definition">¶</a></dt>
-<dd><p>Creates a new JavaScript runtime. JS objects created by the runtime
-may only interact with other JS objects of the same runtime.</p>
-<p>With few exceptions, objects belonging to a runtime can currently
-only be used in the same thread that the runtime was created
-in. This may be changed in the future, since SpiderMonkey itself
-has support for thread safety.</p>
-<p>JS runtimes are weak-referencable.</p>
-<dl class="method">
-<dt id="pymonkey.Runtime.new_context">
-<tt class="descname">new_context</tt><big>(</big><big>)</big><a class="headerlink" href="#pymonkey.Runtime.new_context" title="Permalink to this definition">¶</a></dt>
-<dd>Creates a new Context object and returns it. Contexts are best
-conceptualized as threads of execution in a JS runtme; each one
-has a program counter, a current exception state, and so
-forth. JS objects may be freely accessed and changed by contexts
-that are associated with the same JS runtime as the objects.</dd></dl>
-
-</dd></dl>
-
-</div>
-
-
-          </div>
-        </div>
-      </div>
-      <div class="sphinxsidebar">
-        <div class="sphinxsidebarwrapper">
-            <h4>Previous topic</h4>
-            <p class="topless"><a href="index.html"
-                                  title="previous chapter">Pymonkey Documentation</a></p>
-            <h3>This Page</h3>
-            <ul class="this-page-menu">
-              <li><a href="_sources/pymonkey.txt"
-                     rel="nofollow">Show Source</a></li>
-            </ul>
-          <div id="searchbox" style="display: none">
-            <h3>Quick search</h3>
-              <form class="search" action="search.html" method="get">
-                <input type="text" name="q" size="18" />
-                <input type="submit" value="Go" />
-                <input type="hidden" name="check_keywords" value="yes" />
-                <input type="hidden" name="area" value="default" />
-              </form>
-              <p class="searchtip" style="font-size: 90%">
-              Enter search terms or a module, class or function name.
-              </p>
-          </div>
-          <script type="text/javascript">$('#searchbox').show(0);</script>
-        </div>
-      </div>
-      <div class="clearer"></div>
-    </div>
-    <div class="related">
-      <h3>Navigation</h3>
-      <ul>
-        <li class="right" style="margin-right: 10px">
-          <a href="genindex.html" title="General Index"
-             >index</a></li>
-        <li class="right" >
-          <a href="modindex.html" title="Global Module Index"
-             >modules</a> |</li>
-        <li class="right" >
-          <a href="index.html" title="Pymonkey Documentation"
-             >previous</a> |</li>
-        <li><a href="index.html">Pymonkey v0.0.1 documentation</a> &raquo;</li> 
-      </ul>
-    </div>
-    <div class="footer">
-      &copy; Copyright 2009, Atul Varma.
-      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.2.
-    </div>
-  </body>
-</html>
\ No newline at end of file
--- a/docs/rendered/search.html	Sun Aug 30 20:56:43 2009 -0700
+++ b/docs/rendered/search.html	Tue Sep 01 03:07:24 2009 -0700
@@ -5,7 +5,7 @@
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     
-    <title>Search &mdash; Pymonkey v0.0.1 documentation</title>
+    <title>Search &mdash; Pydermonkey v0.0.1 documentation</title>
     <link rel="stylesheet" href="_static/default.css" type="text/css" />
     <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
     <script type="text/javascript">
@@ -20,7 +20,7 @@
     <script type="text/javascript" src="_static/jquery.js"></script>
     <script type="text/javascript" src="_static/doctools.js"></script>
     <script type="text/javascript" src="_static/searchtools.js"></script>
-    <link rel="top" title="Pymonkey v0.0.1 documentation" href="index.html" /> 
+    <link rel="top" title="Pydermonkey v0.0.1 documentation" href="index.html" /> 
   </head>
   <body>
     <div class="related">
@@ -32,7 +32,7 @@
         <li class="right" >
           <a href="modindex.html" title="Global Module Index"
              accesskey="M">modules</a> |</li>
-        <li><a href="index.html">Pymonkey v0.0.1 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Pydermonkey v0.0.1 documentation</a> &raquo;</li> 
       </ul>
     </div>  
 
@@ -83,7 +83,7 @@
         <li class="right" >
           <a href="modindex.html" title="Global Module Index"
              >modules</a> |</li>
-        <li><a href="index.html">Pymonkey v0.0.1 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Pydermonkey v0.0.1 documentation</a> &raquo;</li> 
       </ul>
     </div>
   
--- a/docs/rendered/searchindex.js	Sun Aug 30 20:56:43 2009 -0700
+++ b/docs/rendered/searchindex.js	Tue Sep 01 03:07:24 2009 -0700
@@ -1,1 +1,1 @@
-Search.setIndex({desctypes:{"0":"method","1":"data","2":"class","3":"exception"},terms:{spidermonkei:[0,1],represent:1,all:[0,1],code:[0,1],untrust:0,lack:0,concept:0,sleep:1,follow:1,privat:1,depend:0,readabl:0,program:1,isinst:1,sourc:1,string:1,veri:[0,1],join:[],vast:0,level:1,"try":[0,1],eas:0,second:1,pass:1,casual:0,even:[],index:[0,1],what:[],conceptu:1,evaluate_script:1,abl:0,"while":1,access:[0,1],"new":1,objdir:[],method:1,metadata:1,involv:0,full:0,subtyp:1,never:0,new_object:1,here:[0,1],objcec:[],path:[],sinc:1,valu:1,convert:1,amount:1,has_properti:1,doctest:0,action:1,chang:1,tremend:0,via:[0,1],modul:[0,1],filenam:1,api:0,instal:0,test_pymonkei:[],from:[0,1],would:0,memori:0,init_standard_class:1,line_ext:1,few:1,disambigu:1,scope:1,type:1,more:[0,1],thisobj:1,mozilla:[0,1],ctype:0,oop:1,known:0,central:[],must:0,none:1,retriev:1,setup:0,work:0,compile_script:1,abort:1,can:[0,1],learn:0,akin:0,root:0,fetch:0,def:1,give:0,process:0,challeng:0,sudo:0,indic:0,carrot:1,want:[0,1],alwai:0,goal:0,secur:[0,1],write:0,how:0,verifi:1,map:1,product:0,referenc:1,clone:[],usabl:0,befor:0,mai:1,data:1,third:[0,1],counter:1,callback:1,sandbox:0,environ:0,enter:[],callabl:1,oper:1,becaus:0,intermediari:0,through:1,dynam:0,bytecod:1,platform:0,window:0,pend:1,is_python:1,bypass:1,easier:0,them:0,within:1,"return":1,thei:[],python:[0,1],safe:1,now:1,xpcom:0,name:1,anyth:0,get_runtim:1,easili:0,trigger_operation_callback:1,trap:0,compris:1,each:1,debug:[0,1],side:0,mean:0,compil:[0,1],realli:0,ensur:0,"static":[],collector:0,special:1,out:0,safeti:1,path_to_objdir:[],profil:0,lineno:1,rational:0,print:1,forth:1,math:1,model:0,situat:0,free:[],standard:[0,1],reason:1,base:0,dictionari:1,thrown:1,etern:1,thread:1,traceback:[0,1],isn:1,caught:1,first:1,origin:1,singleton:1,obviou:0,pyrex:0,feel:[],onc:1,arrai:1,number:[0,1],get_properti:1,hook:1,instruct:[],facil:0,given:1,script:1,associ:1,interact:1,stack:[0,1],too:[0,1],"final":0,store:1,relationship:0,beet:1,tool:[],huh:[],took:1,specifi:1,getter:1,than:0,wide:0,kind:[],target:1,whenev:1,provid:[0,1],posit:1,browser:0,pre:1,comput:1,falsi:1,arg:1,argument:1,packag:0,have:[0,1],tabl:0,need:[0,1],"null":1,engin:[0,1],built:1,equival:1,inform:1,latter:[],client:0,note:[0,1],also:[0,1],ideal:0,without:0,build:0,which:[0,1],noth:[0,1],begin:1,trace:1,though:1,buffer:1,object:[0,1],most:1,plai:0,"class":1,don:0,exc:1,clear:1,later:1,doe:1,runtim:1,awesom:0,text:1,particularli:0,find:1,setter:1,define_properti:1,current:[0,1],onli:[0,1],just:1,solut:0,should:0,busi:0,obj1:1,obj2:1,contribut:0,get:1,get_pending_except:1,stop:1,pave:0,increas:0,requir:0,enabl:0,yield:1,contain:1,where:[0,1],set:1,new_context:1,frame:1,see:1,result:1,stop_running_cod:1,disadvantag:0,best:1,page:0,detect:0,someth:0,state:1,won:0,outstand:0,between:[0,1],atul:0,"import":1,call_funct:1,watchdog_thread:1,kei:1,javascript:[0,1],weak:1,cycl:0,preprocessor:0,complementari:0,come:1,last:1,easi:0,extens:0,howev:0,blargh:[],instanc:[0,1],context:[0,1],logic:0,freeli:1,com:[],private_obj:1,unclear:[],simpli:[],sweep:0,header:0,assum:1,duplic:0,quit:0,java:0,creat:[0,1],three:1,been:1,mark:0,trigger:1,clear_object_priv:[0,1],search:0,ani:[0,1],togeth:1,func:1,base_lineno:1,ident:1,straight:0,properti:1,durat:1,defin:[0,1],invok:1,error:1,propag:1,advantag:0,unintuit:[],readm:[],contributor:0,blah:[],itself:1,is_exception_pend:1,develop:0,perform:1,parti:0,make:0,belong:1,cross:0,same:1,preserv:1,complex:0,document:[0,1],http:[],wherea:0,effect:1,hand:0,fairli:0,moment:[],rais:1,get_stack:1,implement:1,pymonkei:[0,1],recent:1,off:[],macro:0,exampl:1,thi:[0,1],undefin:1,programm:0,everyth:0,know:[],new_funct:1,execut:[0,1],less:0,when:1,obtain:[],yet:1,languag:0,web:0,expos:[0,1],except:1,add:1,valid:0,get_object_priv:1,els:1,take:1,around:0,read:[0,1],swig:0,envis:0,capi:0,world:0,bit:0,like:[0,1],vibrant:0,manual:0,resolv:0,server:0,collect:[0,1],set_throw_hook:1,either:[],docutil:1,manag:[],right:[],some:[0,1],back:[],global:1,mirror:[],librari:0,subclass:1,rhino:0,foo:1,refer:0,run:[0,1],garbag:[0,1],broken:0,set_operation_callback:1,repositori:0,throwhook:1,"throw":1,about:[0,1],actual:[0,1],unfortun:[],js_initstandardclass:1,due:0,empti:1,serverj:0,wrap:1,watchdog:1,your:0,execute_script:1,span:1,wai:0,ergonom:0,support:1,"long":1,custom:0,avail:[0,1],start:1,interfac:1,low:1,lot:0,suit:0,call:1,"function":[0,1],properli:0,offer:1,tupl:1,globalobj:1,line:1,"true":1,count:0,made:0,possibl:[0,1],whether:1,caller:1,otherwis:1,similar:0,featur:0,evalu:1,runtm:1,doesn:[0,1],repres:1,exist:[0,1],file:[0,1],check:[],probabl:0,floor:1,boop:[],todo:[],nan:1,field:0,other:[0,1],role:[],futur:1,test:0,you:[0,1],boof:[],matur:0,relat:1,liter:1,eval:1,unbind:1,land:[0,1],sphinx:0,directori:[],descript:1,obj:1,time:[0,1]},titles:["Pymonkey Documentation","<tt class=\"docutils literal docutils literal\"><span class=\"pre\">pymonkey</span></tt> &#8212; Access SpiderMonkey from Python"],modules:{pymonkey:1},descrefs:{"pymonkey.Runtime":{new_context:[1,0]},"pymonkey.Script":{base_lineno:[1,1],line_extent:[1,1],filename:[1,1]},"pymonkey.Context":{get_object_private:[1,0],get_property:[1,0],new_object:[1,0],has_property:[1,0],call_function:[1,0],trigger_operation_callback:[1,0],evaluate_script:[1,0],clear_object_private:[1,0],new_function:[1,0],init_standard_classes:[1,0],define_property:[1,0],compile_script:[1,0],set_operation_callback:[1,0],set_throw_hook:[1,0],gc:[1,0],get_runtime:[1,0],get_stack:[1,0],get_pending_exception:[1,0],is_exception_pending:[1,0],execute_script:[1,0]},pymonkey:{Function:[1,2],undefined:[1,1],Script:[1,2],Object:[1,2],Context:[1,2],error:[1,3],Runtime:[1,2]},"pymonkey.Function":{base_lineno:[1,1],is_python:[1,1],line_extent:[1,1],filename:[1,1]},"pymonkey.Object":{get_runtime:[1,0]}},filenames:["index","pymonkey"]})
\ No newline at end of file
+Search.setIndex({desctypes:{"0":"method","1":"data","2":"class","3":"exception"},terms:{spidermonkei:[0,1],represent:1,all:[0,1],code:[0,1],untrust:0,lack:0,concept:0,sleep:1,follow:1,privat:1,depend:0,readabl:0,program:1,isinst:1,sourc:1,string:1,veri:[0,1],join:[],vast:0,level:1,"try":[0,1],eas:0,second:1,pass:1,casual:0,even:[],index:[0,1],what:[],conceptu:1,evaluate_script:1,abl:0,"while":1,access:[0,1],"new":1,objdir:[],method:1,metadata:1,involv:0,full:0,subtyp:1,never:0,new_object:1,here:[0,1],objcec:[],path:[],sinc:1,valu:1,convert:1,amount:1,has_properti:1,doctest:0,action:1,chang:1,tremend:0,via:[0,1],modul:[0,1],filenam:1,api:0,instal:0,test_pymonkei:[],from:[0,1],would:0,memori:0,init_standard_class:1,line_ext:1,few:1,disambigu:1,scope:1,type:1,more:[0,1],thisobj:1,mozilla:[0,1],ctype:0,oop:1,known:0,central:[],must:0,none:1,retriev:1,setup:0,work:0,compile_script:1,abort:1,can:[0,1],learn:0,akin:0,root:0,fetch:0,def:1,give:0,process:0,challeng:0,sudo:0,indic:0,carrot:1,want:[0,1],alwai:0,goal:0,secur:[0,1],write:0,how:0,verifi:1,map:1,product:0,referenc:1,clone:[],usabl:0,befor:0,mai:1,data:1,third:[0,1],counter:1,callback:1,sandbox:0,environ:0,enter:[],callabl:1,oper:1,becaus:0,intermediari:0,through:1,dynam:0,bytecod:1,platform:0,window:0,pend:1,is_python:1,bypass:1,easier:0,them:0,within:1,"return":1,thei:[],python:[0,1],safe:1,now:1,xpcom:0,name:1,anyth:0,get_runtim:1,easili:0,trigger_operation_callback:1,trap:0,compris:1,each:1,debug:[0,1],side:0,mean:0,compil:[0,1],realli:0,ensur:0,"static":[],collector:0,special:1,out:0,safeti:1,path_to_objdir:[],profil:0,lineno:1,rational:0,print:1,forth:1,math:1,model:0,situat:0,free:[],standard:[0,1],reason:1,base:0,dictionari:1,thrown:1,etern:1,thread:1,traceback:[0,1],isn:1,caught:1,first:1,origin:1,singleton:1,obviou:0,pyrex:0,feel:[],onc:1,arrai:1,number:[0,1],get_properti:1,hook:1,instruct:[],facil:0,given:1,script:1,associ:1,interact:1,stack:[0,1],too:[0,1],"final":0,store:1,relationship:0,beet:1,tool:[],huh:[],took:1,specifi:1,getter:1,than:0,wide:0,kind:[],target:1,whenev:1,provid:[0,1],posit:1,browser:0,pre:1,comput:1,falsi:1,arg:1,argument:1,packag:0,have:[0,1],tabl:0,need:[0,1],"null":1,engin:[0,1],built:1,equival:1,inform:1,latter:[],client:0,note:[0,1],also:[0,1],ideal:0,without:0,build:0,which:[0,1],noth:[0,1],begin:1,trace:1,though:1,buffer:1,object:[0,1],most:1,plai:0,"class":1,don:0,exc:1,clear:1,later:1,doe:1,runtim:1,awesom:0,text:1,particularli:0,find:1,setter:1,define_properti:1,current:[0,1],onli:[0,1],just:1,solut:0,should:0,busi:0,obj1:1,obj2:1,contribut:0,get:1,get_pending_except:1,stop:1,pave:0,increas:0,requir:0,enabl:0,yield:1,contain:1,where:[0,1],set:1,new_context:1,frame:1,see:1,result:1,stop_running_cod:1,disadvantag:0,best:1,page:0,detect:0,someth:0,state:1,won:0,outstand:0,between:[0,1],atul:0,"import":1,call_funct:1,watchdog_thread:1,kei:1,javascript:[0,1],weak:1,cycl:0,preprocessor:0,complementari:0,come:1,last:1,easi:0,extens:0,howev:0,blargh:[],instanc:[0,1],context:[0,1],logic:0,freeli:1,com:[],private_obj:1,unclear:[],simpli:[],sweep:0,header:0,assum:1,duplic:0,quit:0,java:0,creat:[0,1],three:1,been:1,mark:0,trigger:1,clear_object_priv:[0,1],search:0,ani:[0,1],togeth:1,func:1,base_lineno:1,ident:1,straight:0,properti:1,durat:1,defin:[0,1],invok:1,error:1,propag:1,advantag:0,unintuit:[],readm:[],contributor:0,blah:[],itself:1,is_exception_pend:1,develop:0,perform:1,parti:0,make:0,belong:1,cross:0,same:1,preserv:1,complex:0,document:[0,1],http:[],wherea:0,effect:1,hand:0,fairli:0,moment:[],rais:1,get_stack:1,implement:1,pymonkei:[0,1],recent:1,off:[],macro:0,exampl:1,thi:[0,1],undefin:1,programm:0,everyth:0,know:[],new_funct:1,execut:[0,1],less:0,when:1,obtain:[],yet:1,languag:0,web:0,expos:[0,1],except:1,add:1,valid:0,get_object_priv:1,els:1,take:1,around:0,read:[0,1],swig:0,envis:0,capi:0,world:0,bit:0,like:[0,1],vibrant:0,manual:0,resolv:0,server:0,collect:[0,1],set_throw_hook:1,either:[],docutil:1,manag:[],right:[],some:[0,1],back:[],global:1,mirror:[],librari:0,subclass:1,rhino:0,foo:1,refer:0,run:[0,1],garbag:[0,1],broken:0,set_operation_callback:1,repositori:0,throwhook:1,"throw":1,about:[0,1],actual:[0,1],unfortun:[],js_initstandardclass:1,due:0,empti:1,serverj:0,wrap:1,watchdog:1,your:0,execute_script:1,span:1,wai:0,ergonom:0,support:1,"long":1,custom:0,avail:[0,1],start:1,interfac:1,low:1,lot:0,suit:0,call:1,"function":[0,1],properli:0,offer:1,tupl:1,globalobj:1,line:1,"true":1,count:0,made:0,possibl:[0,1],whether:1,caller:1,otherwis:1,similar:0,featur:0,evalu:1,runtm:1,doesn:[0,1],repres:1,exist:[0,1],file:[0,1],check:[],probabl:0,floor:1,boop:[],todo:[],nan:1,field:0,other:[0,1],role:[],futur:1,test:0,you:[0,1],boof:[],matur:0,relat:1,liter:1,eval:1,unbind:1,land:[0,1],sphinx:0,directori:[],descript:1,obj:1,time:[0,1]},titles:["Pydermonkey Documentation","<tt class=\"docutils literal docutils literal\"><span class=\"pre\">pydermonkey</span></tt> &#8212; Access SpiderMonkey from Python"],modules:{pydermonkey:1},descrefs:{"pydermonkey.Runtime":{new_context:[1,0]},"pydermonkey.Script":{base_lineno:[1,1],line_extent:[1,1],filename:[1,1]},"pydermonkey.Context":{get_object_private:[1,0],get_property:[1,0],new_object:[1,0],has_property:[1,0],call_function:[1,0],trigger_operation_callback:[1,0],evaluate_script:[1,0],clear_object_private:[1,0],new_function:[1,0],init_standard_classes:[1,0],define_property:[1,0],compile_script:[1,0],set_operation_callback:[1,0],set_throw_hook:[1,0],gc:[1,0],get_runtime:[1,0],get_stack:[1,0],get_pending_exception:[1,0],is_exception_pending:[1,0],execute_script:[1,0]},pydermonkey:{Function:[1,2],undefined:[1,1],Script:[1,2],Object:[1,2],Context:[1,2],error:[1,3],Runtime:[1,2]},"pydermonkey.Function":{base_lineno:[1,1],is_python:[1,1],line_extent:[1,1],filename:[1,1]},"pydermonkey.Object":{get_runtime:[1,0]}},filenames:["index","pydermonkey"]})
\ No newline at end of file
--- a/docs/src/conf.py	Sun Aug 30 20:56:43 2009 -0700
+++ b/docs/src/conf.py	Tue Sep 01 03:07:24 2009 -0700
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Pymonkey documentation build configuration file, created by
+# Pydermonkey documentation build configuration file, created by
 # sphinx-quickstart on Mon Jul  6 17:20:31 2009.
 #
 # This file is execfile()d with the current directory set to its containing dir.
@@ -37,7 +37,7 @@
 master_doc = 'index'
 
 # General information about the project.
-project = u'Pymonkey'
+project = u'Pydermonkey'
 copyright = u'2009, Atul Varma'
 
 # The version info for the project you're documenting, acts as replacement for
@@ -158,7 +158,7 @@
 #html_file_suffix = ''
 
 # Output file base name for HTML help builder.
-htmlhelp_basename = 'Pymonkeydoc'
+htmlhelp_basename = 'Pydermonkeydoc'
 
 
 # -- Options for LaTeX output --------------------------------------------------
@@ -172,7 +172,7 @@
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title, author, documentclass [howto/manual]).
 latex_documents = [
-  ('index', 'Pymonkey.tex', u'Pymonkey Documentation',
+  ('index', 'Pydermonkey.tex', u'Pydermonkey Documentation',
    u'Atul Varma', 'manual'),
 ]
 
--- a/docs/src/index.txt	Sun Aug 30 20:56:43 2009 -0700
+++ b/docs/src/index.txt	Tue Sep 01 03:07:24 2009 -0700
@@ -1,20 +1,20 @@
-.. Pymonkey documentation master file, created by
+.. Pydermonkey documentation master file, created by
    sphinx-quickstart on Mon Jul  6 17:20:31 2009.
    You can adapt this file completely to your liking, but it should at least
    contain the root `toctree` directive.
 
 ======================
-Pymonkey Documentation
+Pydermonkey Documentation
 ======================
 
-Pymonkey is a Python C extension module to expose the `Mozilla
+Pydermonkey is a Python C extension module to expose the `Mozilla
 SpiderMonkey <https://developer.mozilla.org/en/SpiderMonkey>`_ engine
 to Python.
 
 .. toctree::
    :maxdepth: 2
 
-   pymonkey
+   pydermonkey
 
 Rationale and Goals:
 
@@ -34,17 +34,17 @@
   <https://wiki.mozilla.org/ServerJS>`_ are currently paving the way
   in this field. There's Java-based solutions like Rhino out there,
   but nothing really mature is available for the Python
-  world. Ideally, Pymonkey should enable a Python programmer to create
+  world. Ideally, Pydermonkey should enable a Python programmer to create
   a custom sandboxed environment for executing JS code without needing
   to write any C.
 
-* Pymonkey should have awesome Sphinx documentation with doctests and
+* Pydermonkey should have awesome Sphinx documentation with doctests and
   all the trappings of a model Python package. Not only should it be
   easy for Python programmers to learn how to use the module, but it
   should also be easy for them to learn more about how SpiderMonkey
   works by reading the documentation and playing around with the code.
 
-* Pymonkey needs to have outstanding developer ergonomics. Full
+* Pydermonkey needs to have outstanding developer ergonomics. Full
   cross-language stack tracebacks should be available, for instance,
   and developers should be able to easily debug. Access to memory
   profiling facilities in JS-land is a must.
@@ -69,7 +69,7 @@
 Building, Testing, and Installing
 =================================
 
-From the root of your pymonkey repository, run::
+From the root of your pydermonkey repository, run::
 
   python setup.py build test
 
@@ -86,7 +86,7 @@
 ==========
 
 There's a number of challenges that need to be resolved before
-pymonkey can be really usable. Here's some of them.
+pydermonkey can be really usable. Here's some of them.
 
 **Garbage Collection**
 
@@ -100,7 +100,7 @@
 <https://developer.mozilla.org/en/Interfacing_with_the_XPCOM_cycle_collector>`_.
 
 For the time being, however, such cycles can be manually broken via
-:meth:`pymonkey.Context.clear_object_private()` on valid objects and functions.
+:meth:`pydermonkey.Context.clear_object_private()` on valid objects and functions.
 
 Indices and Tables
 ==================
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/src/pydermonkey.txt	Tue Sep 01 03:07:24 2009 -0700
@@ -0,0 +1,446 @@
+:mod:`pydermonkey` --- Access SpiderMonkey from Python
+===================================================
+
+.. module:: pydermonkey
+   :synopsis: Access SpiderMonkey from Python
+
+.. testsetup:: *
+
+   import pydermonkey
+
+This module offers a low-level interface to the `Mozilla SpiderMonkey
+<https://developer.mozilla.org/en/SpiderMonkey>`_ JavaScript engine.
+
+.. exception:: error
+
+   This is the type of any SpiderMonkey-related errors thrown by this
+   module.
+
+   If the error is a wrapped JavaScript exception, the first argument
+   will be the thrown JS exception, and the second argument will be 
+   the JS exception converted to a string. Otherwise, the error
+   will only contain a descriptive string argument.
+
+   For example:
+
+     >>> cx = pydermonkey.Runtime().new_context()
+     >>> cx.evaluate_script(cx.new_object(), 'throw 1', '<string>', 1)
+     Traceback (most recent call last):
+     ...
+     error: (1, u'1')
+
+.. data:: undefined
+
+   This is the singleton that represents the JavaScript value
+   ``undefined``, as Python has no equivalent representation
+   (JavaScript's ``null`` is mapped to Python's ``None`` object).
+   For instance:
+
+     >>> cx = pydermonkey.Runtime().new_context()
+     >>> cx.evaluate_script(cx.new_object(), '', '<string>', 1)
+     pydermonkey.undefined
+
+   This object also has a "falsy" value:
+
+     >>> if not pydermonkey.undefined:
+     ...   print "See, it's falsy!"
+     See, it's falsy!
+
+.. class:: Object
+
+   This is the type of JavaScript objects. Such objects can only be
+   created via Pydermonkey calls like :meth:`Context.new_object()` or
+   through the execution of JS code, but this type object can be used
+   with Python's built-in :func:`isinstance()` to verify that an
+   object is a JS object, like so:
+
+     >>> obj = pydermonkey.Runtime().new_context().new_object()
+     >>> isinstance(obj, pydermonkey.Object)
+     True
+
+   Note that :class:`Object` and all its subclasses are
+   identity-preserving when passed between Python and
+   JavaScript code. For instance:
+
+     >>> cx = pydermonkey.Runtime().new_context()
+     >>> obj1 = cx.new_object()
+     >>> obj2 = cx.evaluate_script(obj1, 'this', '<string>', 1)
+     >>> obj1 is obj2
+     True
+
+   .. method:: get_runtime()
+
+      Returns the :class:`Runtime` that the object belongs to.
+
+.. class:: Function
+
+   This is the type of JavaScript functions, which is a subtype of
+   :class:`Object`.
+
+   .. data:: filename
+
+      Name of the file that contains the function's original JS source
+      code. If the function isn't a JS function, this value is
+      ``None``.
+
+   .. data:: base_lineno
+
+      The line number at which the function's JS source code begins.
+
+   .. data:: line_extent
+
+      The number of lines comprising the function's JS source code.
+
+   .. data:: is_python
+
+      Whether or not the function is actually implemented in Python.
+      If it is, you can use :meth:`Context.get_object_private()` to
+      retrieve this Python function.
+
+.. class:: Script
+
+   This is the type of compiled JavaScript scripts; it's actually a
+   subtype of :class:`Object`, though when exposed to JS code it
+   doesn't provide access to any special data or functionality.
+
+   Script instances have a read-only buffer interface that exposes
+   their bytecode. This can be accessed by passing an instance to
+   Python's built-in ``buffer()`` function.
+
+   .. data:: filename
+
+      The filename of the script's original source code.
+
+   .. data:: base_lineno
+
+      The line number at which the script's original source code
+      begins.
+
+   .. data:: line_extent
+
+      The number of lines comprising the original source code.
+
+.. class:: Context
+
+   This is the type of JavaScript context objects. Contexts can only
+   be created via a call to :meth:`Runtime.new_context()`, but this
+   type object can be used with Python's built-in :func:`isinstance()`
+   to verify that an object is a context, like so:
+
+     >>> cx = pydermonkey.Runtime().new_context()
+     >>> isinstance(cx, pydermonkey.Context)
+     True
+
+   JS contexts are weak-referencable.
+
+   .. method:: get_runtime()
+
+      Returns the :class:`Runtime` that the context belongs to.
+
+   .. method:: get_stack()
+
+      Returns a dictionary containing information about the context's
+      current stack.
+
+      The dictionary contains the following string keys:
+
+      +------------------------------+-------------------------------------+
+      | key                          | value                               |
+      +==============================+=====================================+
+      | :const:`script`              | :class:`Script` of the frame.       |
+      |                              | This may be ``None`` if the frame   |
+      |                              | isn't a scripted frame, or if it's  |
+      |                              | not possible to expose the script   |
+      |                              | to Python for some reason.          |
+      +------------------------------+-------------------------------------+
+      | :const:`lineno`              | Line number of the frame, if the    |
+      |                              | frame is scripted.                  |
+      +------------------------------+-------------------------------------+
+      | :const:`pc`                  | Program counter of the frame; this  |
+      |                              | is an index into the bytecode of    |
+      |                              | the frame's script, if the frame    |
+      |                              | is scripted.                        |
+      +------------------------------+-------------------------------------+
+      | :const:`function`            | The :class:`Function` in which the  |
+      |                              | frame is executing, if any.         |
+      +------------------------------+-------------------------------------+
+      | :const:`caller`              | Dictionary containing information   |
+      |                              | about the stack frame of the        |
+      |                              | caller of this frame. If this frame |
+      |                              | has no caller, this value is        |
+      |                              | ``None``.                           |
+      +------------------------------+-------------------------------------+
+
+      If the context isn't currently executing any code (i.e., the stack
+      is empty), this method returns ``None``.
+
+   .. method:: new_object([private_obj])
+
+      Creates a new :class:`Object` instance and returns
+      it. ``private_obj`` is any Python object that is privately
+      stored within the new JS object; it can be retrieved using
+      :meth:`get_object_private()`.
+
+   .. method:: new_function(func, name)
+
+      Creates a new :class:`Function` instance that wraps the
+      given Python callable.  In JS-land, the function will
+      have the given name.
+
+      When the function is executed from JavaScript, `func`
+      will be passed three positional arguments.
+
+      The first argument is a :class:`Context` that represents the
+      JS context which is calling the function.
+
+      The second argument is an :class:`Object` that represents the
+      value of ``this`` for the duration of the call.
+
+      The third argument is a tuple containing the arguments
+      passed to the function.
+
+      For instance:
+
+        >>> def add(cx, this, args):
+        ...   return args[0] + args[1]
+        >>> cx = pydermonkey.Runtime().new_context()
+        >>> obj = cx.new_object()
+        >>> cx.define_property(obj, 'add', cx.new_function(add, 'add'))
+        >>> cx.evaluate_script(obj, 'add(1, 1);', '<string>', 1)
+        2
+
+   .. method:: define_property(object, name, value)
+
+      Creates a new property on `object`, bypassing any JavaScript setters.
+
+   .. method:: has_property(object, name)
+
+      Returns whether or not `object` has the specified property.
+
+   .. method:: get_property(object, name)
+
+      Finds the specified property on `object` and returns its value,
+      possibly invoking a JavaScript getter.
+
+      Example:
+
+        >>> cx = pydermonkey.Runtime().new_context()
+        >>> obj = cx.new_object()
+        >>> cx.define_property(obj, 'beets', 'i like beets.')
+        >>> cx.get_property(obj, 'beets')
+        u'i like beets.'
+
+      Note also that calling this function on undefined properties
+      yields :data:`undefined`:
+
+        >>> cx.get_property(obj, 'carrots')
+        pydermonkey.undefined
+
+   .. method:: get_object_private(object)
+
+      Returns the ``private_obj`` passed to :meth:`new_object()`
+      when `object` was first created. If it doesn't exist, ``None``
+      is returned.
+
+      If `object` was created with :meth:`new_function()`, then this
+      method returns the Python callable wrapped by `object`.
+
+      This functionality is useful if you want to securely represent
+      Python objects in JS-land.
+
+   .. method:: clear_object_private(object)
+
+      Clears the ``private_obj`` passed to :meth:`new_object()`
+      when `object` was first created. If it doesn't exist, this
+      function returns nothing.
+
+      If `object` was created with :meth:`new_function()`, then this
+      method effectively "unbinds" the Python callable wrapped by
+      `object`. If `object` is later called, an exception will be
+      raised.
+
+   .. method:: evaluate_script(globalobj, code, filename, lineno)
+
+      Evaluates the text `code` using `globalobj` as the global
+      object/scope.
+
+      It's assumed that `code` is coming from the file named by `filename`;
+      the first line of `code` is assumed to be line number `lineno` of
+      `filename`. This metadata is very useful for debugging stack traces,
+      exceptions, and so forth.
+
+      For example:
+
+        >>> cx = pydermonkey.Runtime().new_context()
+        >>> obj = cx.new_object()
+        >>> cx.init_standard_classes(obj)
+        >>> cx.evaluate_script(obj, '5 * Math', '<string>', 1)
+        nan
+
+   .. method:: compile_script(code, filename, lineno)
+
+      Compiles the given string of code and returns a :class:`Script`
+      instance that can be executed via :meth:`execute_script()`.
+
+      `filename` and `lineno` are used just as in
+      :meth:`evaluate_script()`.
+
+   .. method:: execute_script(globalobj, script)
+
+      Executes the code in the given :class:`Script` object, using
+      `globalobj` as the global object/scope, and returns the result.
+
+      For example:
+
+        >>> cx = pydermonkey.Runtime().new_context()
+        >>> obj = cx.new_object()
+        >>> cx.init_standard_classes(obj)
+        >>> script = cx.compile_script('5 * Math', '<string>', 1)
+        >>> cx.execute_script(obj, script)
+        nan
+
+   .. method:: call_function(thisobj, func, args)
+
+      Calls a JavaScript function.
+
+      `thisobj` is an :class:`Object` that will be used as the value
+      of ``this`` when the function executes, `func` is the
+      :class:`Function` to execute, and `args` is a tuple of arguments
+      to pass to the function.
+
+      For instance:
+
+        >>> cx = pydermonkey.Runtime().new_context()
+        >>> obj = cx.new_object()
+        >>> cx.init_standard_classes(obj)
+        >>> Math = cx.get_property(obj, 'Math')
+        >>> floor = cx.get_property(Math, 'floor')
+        >>> cx.call_function(Math, floor, (5.3,))
+        5
+
+   .. method:: init_standard_classes(object)
+
+      Defines the standard JavaScript classes on the given
+      :class:`Object`, such as ``Array``, ``eval``, ``undefined``, and
+      so forth. For more information, see the documentation to
+      `JS_InitStandardClasses()
+      <https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_InitStandardClasses>`_,
+      which this method wraps.
+
+   .. method:: gc()
+
+      Performs garbage collection on the context's JavaScript runtime.
+
+   .. method:: is_exception_pending()
+
+      Returns whether an exception is currently being propagated in
+      the context.
+
+   .. method:: get_pending_exception()
+
+      Returns the current exception being propagated in the context. If
+      no exception is being propagated, this method returns ``None``.
+
+      If you need to disambiguate between whether ``None`` is the
+      pending exception or there is no pending exception, use
+      :meth:`is_exception_pending()`.
+
+   .. method:: set_throw_hook(func)
+
+      Sets the throw hook for the context to the given Python callable.
+      The hook is triggered whenever an exception is thrown in the
+      context.
+
+      `func` takes one argument: the context that triggered it.
+
+      For example, here's a throw hook that prints information about
+      an exception as it's being propagated through the stack:
+
+        >>> def throwhook(cx): 
+        ...   stack = cx.get_stack()
+        ...   if stack['function']:
+        ...     where = stack['function'].name
+        ...   else:
+        ...     where = stack['script'].filename
+        ...   exc = cx.get_pending_exception()
+        ...   print "%s being thrown in %s" % (exc, where)
+
+      Here's the hook in action:
+
+        >>> cx = pydermonkey.Runtime().new_context()
+        >>> cx.set_throw_hook(throwhook)
+        >>> obj = cx.new_object()
+        >>> code = "(function foo() { throw 'oops' })()"
+        >>> try:
+        ...   cx.evaluate_script(obj, code, '<string>', 1)
+        ... except pydermonkey.error, e:
+        ...   print "caught %s" % e.args[0]
+        oops being thrown in foo
+        oops being thrown in <string>
+        caught oops
+
+   .. method:: set_operation_callback(func)
+
+      Sets the operation callback for the context to the given Python
+      callable. The callback can be triggered via
+      :meth:`trigger_operation_callback()`.
+
+      `func` takes one argument: the context that triggered it.
+
+   .. method:: trigger_operation_callback()
+
+      Triggers the context's operation callback. If no callback has
+      yet been set, this function does nothing.
+
+      This function is one of the few thread-safe functions available
+      to a JS runtime, and together with
+      :meth:`set_operation_callback()` can be used to abort the
+      execution of long-running code.
+
+      For instance, we first create an operation callback to stop
+      long-running code by throwing an exception:
+
+        >>> import time, threading
+        >>> cx = pydermonkey.Runtime().new_context()
+        >>> def stop_running_code(cx):
+        ...   raise Exception('JS took too long to execute.')
+        >>> cx.set_operation_callback(stop_running_code)
+
+      Then we create a watchdog thread to trigger the operation
+      callback once a long amount of time has passed:
+
+        >>> def watchdog_thread():
+        ...   time.sleep(0.1)                 # An eternity to a computer!
+        ...   cx.trigger_operation_callback()
+        >>> thread = threading.Thread(target=watchdog_thread)
+        >>> thread.start()
+
+      Now, when we execute code that takes too long to run, it gets
+      aborted:
+
+        >>> try:
+        ...   cx.evaluate_script(cx.new_object(), 'while (1) {}',
+        ...                      '<string>', 1)
+        ... except pydermonkey.error, e:
+        ...   print cx.get_object_private(e.args[0])
+        JS took too long to execute.
+
+.. class:: Runtime()
+
+   Creates a new JavaScript runtime. JS objects created by the runtime
+   may only interact with other JS objects of the same runtime.
+
+   With few exceptions, objects belonging to a runtime can currently
+   only be used in the same thread that the runtime was created
+   in. This may be changed in the future, since SpiderMonkey itself
+   has support for thread safety.
+
+   JS runtimes are weak-referencable.
+
+   .. method:: new_context()
+
+      Creates a new Context object and returns it. Contexts are best
+      conceptualized as threads of execution in a JS runtme; each one
+      has a program counter, a current exception state, and so
+      forth. JS objects may be freely accessed and changed by contexts
+      that are associated with the same JS runtime as the objects.
--- a/docs/src/pymonkey.txt	Sun Aug 30 20:56:43 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,446 +0,0 @@
-:mod:`pymonkey` --- Access SpiderMonkey from Python
-===================================================
-
-.. module:: pymonkey
-   :synopsis: Access SpiderMonkey from Python
-
-.. testsetup:: *
-
-   import pymonkey
-
-This module offers a low-level interface to the `Mozilla SpiderMonkey
-<https://developer.mozilla.org/en/SpiderMonkey>`_ JavaScript engine.
-
-.. exception:: error
-
-   This is the type of any SpiderMonkey-related errors thrown by this
-   module.
-
-   If the error is a wrapped JavaScript exception, the first argument
-   will be the thrown JS exception, and the second argument will be 
-   the JS exception converted to a string. Otherwise, the error
-   will only contain a descriptive string argument.
-
-   For example:
-
-     >>> cx = pymonkey.Runtime().new_context()
-     >>> cx.evaluate_script(cx.new_object(), 'throw 1', '<string>', 1)
-     Traceback (most recent call last):
-     ...
-     error: (1, u'1')
-
-.. data:: undefined
-
-   This is the singleton that represents the JavaScript value
-   ``undefined``, as Python has no equivalent representation
-   (JavaScript's ``null`` is mapped to Python's ``None`` object).
-   For instance:
-
-     >>> cx = pymonkey.Runtime().new_context()
-     >>> cx.evaluate_script(cx.new_object(), '', '<string>', 1)
-     pymonkey.undefined
-
-   This object also has a "falsy" value:
-
-     >>> if not pymonkey.undefined:
-     ...   print "See, it's falsy!"
-     See, it's falsy!
-
-.. class:: Object
-
-   This is the type of JavaScript objects. Such objects can only be
-   created via Pymonkey calls like :meth:`Context.new_object()` or
-   through the execution of JS code, but this type object can be used
-   with Python's built-in :func:`isinstance()` to verify that an
-   object is a JS object, like so:
-
-     >>> obj = pymonkey.Runtime().new_context().new_object()
-     >>> isinstance(obj, pymonkey.Object)
-     True
-
-   Note that :class:`Object` and all its subclasses are
-   identity-preserving when passed between Python and
-   JavaScript code. For instance:
-
-     >>> cx = pymonkey.Runtime().new_context()
-     >>> obj1 = cx.new_object()
-     >>> obj2 = cx.evaluate_script(obj1, 'this', '<string>', 1)
-     >>> obj1 is obj2
-     True
-
-   .. method:: get_runtime()
-
-      Returns the :class:`Runtime` that the object belongs to.
-
-.. class:: Function
-
-   This is the type of JavaScript functions, which is a subtype of
-   :class:`Object`.
-
-   .. data:: filename
-
-      Name of the file that contains the function's original JS source
-      code. If the function isn't a JS function, this value is
-      ``None``.
-
-   .. data:: base_lineno
-
-      The line number at which the function's JS source code begins.
-
-   .. data:: line_extent
-
-      The number of lines comprising the function's JS source code.
-
-   .. data:: is_python
-
-      Whether or not the function is actually implemented in Python.
-      If it is, you can use :meth:`Context.get_object_private()` to
-      retrieve this Python function.
-
-.. class:: Script
-
-   This is the type of compiled JavaScript scripts; it's actually a
-   subtype of :class:`Object`, though when exposed to JS code it
-   doesn't provide access to any special data or functionality.
-
-   Script instances have a read-only buffer interface that exposes
-   their bytecode. This can be accessed by passing an instance to
-   Python's built-in ``buffer()`` function.
-
-   .. data:: filename
-
-      The filename of the script's original source code.
-
-   .. data:: base_lineno
-
-      The line number at which the script's original source code
-      begins.
-
-   .. data:: line_extent
-
-      The number of lines comprising the original source code.
-
-.. class:: Context
-
-   This is the type of JavaScript context objects. Contexts can only
-   be created via a call to :meth:`Runtime.new_context()`, but this
-   type object can be used with Python's built-in :func:`isinstance()`
-   to verify that an object is a context, like so:
-
-     >>> cx = pymonkey.Runtime().new_context()
-     >>> isinstance(cx, pymonkey.Context)
-     True
-
-   JS contexts are weak-referencable.
-
-   .. method:: get_runtime()
-
-      Returns the :class:`Runtime` that the context belongs to.
-
-   .. method:: get_stack()
-
-      Returns a dictionary containing information about the context's
-      current stack.
-
-      The dictionary contains the following string keys:
-
-      +------------------------------+-------------------------------------+
-      | key                          | value                               |
-      +==============================+=====================================+
-      | :const:`script`              | :class:`Script` of the frame.       |
-      |                              | This may be ``None`` if the frame   |
-      |                              | isn't a scripted frame, or if it's  |
-      |                              | not possible to expose the script   |
-      |                              | to Python for some reason.          |
-      +------------------------------+-------------------------------------+
-      | :const:`lineno`              | Line number of the frame, if the    |
-      |                              | frame is scripted.                  |
-      +------------------------------+-------------------------------------+
-      | :const:`pc`                  | Program counter of the frame; this  |
-      |                              | is an index into the bytecode of    |
-      |                              | the frame's script, if the frame    |
-      |                              | is scripted.                        |
-      +------------------------------+-------------------------------------+
-      | :const:`function`            | The :class:`Function` in which the  |
-      |                              | frame is executing, if any.         |
-      +------------------------------+-------------------------------------+
-      | :const:`caller`              | Dictionary containing information   |
-      |                              | about the stack frame of the        |
-      |                              | caller of this frame. If this frame |
-      |                              | has no caller, this value is        |
-      |                              | ``None``.                           |
-      +------------------------------+-------------------------------------+
-
-      If the context isn't currently executing any code (i.e., the stack
-      is empty), this method returns ``None``.
-
-   .. method:: new_object([private_obj])
-
-      Creates a new :class:`Object` instance and returns
-      it. ``private_obj`` is any Python object that is privately
-      stored within the new JS object; it can be retrieved using
-      :meth:`get_object_private()`.
-
-   .. method:: new_function(func, name)
-
-      Creates a new :class:`Function` instance that wraps the
-      given Python callable.  In JS-land, the function will
-      have the given name.
-
-      When the function is executed from JavaScript, `func`
-      will be passed three positional arguments.
-
-      The first argument is a :class:`Context` that represents the
-      JS context which is calling the function.
-
-      The second argument is an :class:`Object` that represents the
-      value of ``this`` for the duration of the call.
-
-      The third argument is a tuple containing the arguments
-      passed to the function.
-
-      For instance:
-
-        >>> def add(cx, this, args):
-        ...   return args[0] + args[1]
-        >>> cx = pymonkey.Runtime().new_context()
-        >>> obj = cx.new_object()
-        >>> cx.define_property(obj, 'add', cx.new_function(add, 'add'))
-        >>> cx.evaluate_script(obj, 'add(1, 1);', '<string>', 1)
-        2
-
-   .. method:: define_property(object, name, value)
-
-      Creates a new property on `object`, bypassing any JavaScript setters.
-
-   .. method:: has_property(object, name)
-
-      Returns whether or not `object` has the specified property.
-
-   .. method:: get_property(object, name)
-
-      Finds the specified property on `object` and returns its value,
-      possibly invoking a JavaScript getter.
-
-      Example:
-
-        >>> cx = pymonkey.Runtime().new_context()
-        >>> obj = cx.new_object()
-        >>> cx.define_property(obj, 'beets', 'i like beets.')
-        >>> cx.get_property(obj, 'beets')
-        u'i like beets.'
-
-      Note also that calling this function on undefined properties
-      yields :data:`undefined`:
-
-        >>> cx.get_property(obj, 'carrots')
-        pymonkey.undefined
-
-   .. method:: get_object_private(object)
-
-      Returns the ``private_obj`` passed to :meth:`new_object()`
-      when `object` was first created. If it doesn't exist, ``None``
-      is returned.
-
-      If `object` was created with :meth:`new_function()`, then this
-      method returns the Python callable wrapped by `object`.
-
-      This functionality is useful if you want to securely represent
-      Python objects in JS-land.
-
-   .. method:: clear_object_private(object)
-
-      Clears the ``private_obj`` passed to :meth:`new_object()`
-      when `object` was first created. If it doesn't exist, this
-      function returns nothing.
-
-      If `object` was created with :meth:`new_function()`, then this
-      method effectively "unbinds" the Python callable wrapped by
-      `object`. If `object` is later called, an exception will be
-      raised.
-
-   .. method:: evaluate_script(globalobj, code, filename, lineno)
-
-      Evaluates the text `code` using `globalobj` as the global
-      object/scope.
-
-      It's assumed that `code` is coming from the file named by `filename`;
-      the first line of `code` is assumed to be line number `lineno` of
-      `filename`. This metadata is very useful for debugging stack traces,
-      exceptions, and so forth.
-
-      For example:
-
-        >>> cx = pymonkey.Runtime().new_context()
-        >>> obj = cx.new_object()
-        >>> cx.init_standard_classes(obj)
-        >>> cx.evaluate_script(obj, '5 * Math', '<string>', 1)
-        nan
-
-   .. method:: compile_script(code, filename, lineno)
-
-      Compiles the given string of code and returns a :class:`Script`
-      instance that can be executed via :meth:`execute_script()`.
-
-      `filename` and `lineno` are used just as in
-      :meth:`evaluate_script()`.
-
-   .. method:: execute_script(globalobj, script)
-
-      Executes the code in the given :class:`Script` object, using
-      `globalobj` as the global object/scope, and returns the result.
-
-      For example:
-
-        >>> cx = pymonkey.Runtime().new_context()
-        >>> obj = cx.new_object()
-        >>> cx.init_standard_classes(obj)
-        >>> script = cx.compile_script('5 * Math', '<string>', 1)
-        >>> cx.execute_script(obj, script)
-        nan
-
-   .. method:: call_function(thisobj, func, args)
-
-      Calls a JavaScript function.
-
-      `thisobj` is an :class:`Object` that will be used as the value
-      of ``this`` when the function executes, `func` is the
-      :class:`Function` to execute, and `args` is a tuple of arguments
-      to pass to the function.
-
-      For instance:
-
-        >>> cx = pymonkey.Runtime().new_context()
-        >>> obj = cx.new_object()
-        >>> cx.init_standard_classes(obj)
-        >>> Math = cx.get_property(obj, 'Math')
-        >>> floor = cx.get_property(Math, 'floor')
-        >>> cx.call_function(Math, floor, (5.3,))
-        5
-
-   .. method:: init_standard_classes(object)
-
-      Defines the standard JavaScript classes on the given
-      :class:`Object`, such as ``Array``, ``eval``, ``undefined``, and
-      so forth. For more information, see the documentation to
-      `JS_InitStandardClasses()
-      <https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_InitStandardClasses>`_,
-      which this method wraps.
-
-   .. method:: gc()
-
-      Performs garbage collection on the context's JavaScript runtime.
-
-   .. method:: is_exception_pending()
-
-      Returns whether an exception is currently being propagated in
-      the context.
-
-   .. method:: get_pending_exception()
-
-      Returns the current exception being propagated in the context. If
-      no exception is being propagated, this method returns ``None``.
-
-      If you need to disambiguate between whether ``None`` is the
-      pending exception or there is no pending exception, use
-      :meth:`is_exception_pending()`.
-
-   .. method:: set_throw_hook(func)
-
-      Sets the throw hook for the context to the given Python callable.
-      The hook is triggered whenever an exception is thrown in the
-      context.
-
-      `func` takes one argument: the context that triggered it.
-
-      For example, here's a throw hook that prints information about
-      an exception as it's being propagated through the stack:
-
-        >>> def throwhook(cx): 
-        ...   stack = cx.get_stack()
-        ...   if stack['function']:
-        ...     where = stack['function'].name
-        ...   else:
-        ...     where = stack['script'].filename
-        ...   exc = cx.get_pending_exception()
-        ...   print "%s being thrown in %s" % (exc, where)
-
-      Here's the hook in action:
-
-        >>> cx = pymonkey.Runtime().new_context()
-        >>> cx.set_throw_hook(throwhook)
-        >>> obj = cx.new_object()
-        >>> code = "(function foo() { throw 'oops' })()"
-        >>> try:
-        ...   cx.evaluate_script(obj, code, '<string>', 1)
-        ... except pymonkey.error, e:
-        ...   print "caught %s" % e.args[0]
-        oops being thrown in foo
-        oops being thrown in <string>
-        caught oops
-
-   .. method:: set_operation_callback(func)
-
-      Sets the operation callback for the context to the given Python
-      callable. The callback can be triggered via
-      :meth:`trigger_operation_callback()`.
-
-      `func` takes one argument: the context that triggered it.
-
-   .. method:: trigger_operation_callback()
-
-      Triggers the context's operation callback. If no callback has
-      yet been set, this function does nothing.
-
-      This function is one of the few thread-safe functions available
-      to a JS runtime, and together with
-      :meth:`set_operation_callback()` can be used to abort the
-      execution of long-running code.
-
-      For instance, we first create an operation callback to stop
-      long-running code by throwing an exception:
-
-        >>> import time, threading
-        >>> cx = pymonkey.Runtime().new_context()
-        >>> def stop_running_code(cx):
-        ...   raise Exception('JS took too long to execute.')
-        >>> cx.set_operation_callback(stop_running_code)
-
-      Then we create a watchdog thread to trigger the operation
-      callback once a long amount of time has passed:
-
-        >>> def watchdog_thread():
-        ...   time.sleep(0.1)                 # An eternity to a computer!
-        ...   cx.trigger_operation_callback()
-        >>> thread = threading.Thread(target=watchdog_thread)
-        >>> thread.start()
-
-      Now, when we execute code that takes too long to run, it gets
-      aborted:
-
-        >>> try:
-        ...   cx.evaluate_script(cx.new_object(), 'while (1) {}',
-        ...                      '<string>', 1)
-        ... except pymonkey.error, e:
-        ...   print cx.get_object_private(e.args[0])
-        JS took too long to execute.
-
-.. class:: Runtime()
-
-   Creates a new JavaScript runtime. JS objects created by the runtime
-   may only interact with other JS objects of the same runtime.
-
-   With few exceptions, objects belonging to a runtime can currently
-   only be used in the same thread that the runtime was created
-   in. This may be changed in the future, since SpiderMonkey itself
-   has support for thread safety.
-
-   JS runtimes are weak-referencable.
-
-   .. method:: new_context()
-
-      Creates a new Context object and returns it. Contexts are best
-      conceptualized as threads of execution in a JS runtme; each one
-      has a program counter, a current exception state, and so
-      forth. JS objects may be freely accessed and changed by contexts
-      that are associated with the same JS runtime as the objects.
--- a/setup.py	Sun Aug 30 20:56:43 2009 -0700
+++ b/setup.py	Tue Sep 01 03:07:24 2009 -0700
@@ -37,7 +37,7 @@
 from paver.easy import *
 from paver.setuputils import setup
 
-SOURCE_FILES = ['pymonkey.cpp',
+SOURCE_FILES = ['pydermonkey.cpp',
                 'utils.cpp',
                 'object.cpp',
                 'function.cpp',
@@ -62,7 +62,7 @@
 DOCTEST_OUTPUT_DIR = os.path.join(BUILD_DIR, 'doctest_output')
 
 setup_options = dict(
-    name='pymonkey',
+    name='pydermonkey',
     version='0.0.1',
     description='Access SpiderMonkey from Python',
     author='Atul Varma',
@@ -92,7 +92,7 @@
     ext_options['libraries'] = ['js_static']
 
 setup_options['ext_modules'] = [
-    distutils.core.Extension('pymonkey',
+    distutils.core.Extension('pydermonkey',
                              [os.path.join("src", filename)
                               for filename in SOURCE_FILES],
                              **ext_options)
@@ -102,7 +102,7 @@
 
 @task
 def docs(options):
-    """Open the Pymonkey documentation in your web browser."""
+    """Open the Pydermonkey documentation in your web browser."""
 
     url = os.path.abspath(os.path.join("docs", "rendered", "index.html"))
     url = urllib.pathname2url(url)
@@ -164,13 +164,13 @@
 @task
 @needs('build_spidermonkey', 'setuptools.command.build')
 def build(options):
-    """Builds the pymonkey extension."""
+    """Builds the pydermonkey extension."""
 
     pass
 
 @task
 def build_docs(options):
-    """Build the Pymonkey documentation (requires Sphinx)."""
+    """Build the Pydermonkey documentation (requires Sphinx)."""
 
     retval = subprocess.call(["sphinx-build",
                               "-b", "html",
@@ -206,7 +206,7 @@
 
 @task
 def test(options):
-    """Test the Pymonkey Python C extension."""
+    """Test the Pydermonkey Python C extension."""
 
     print "Running test suite."
 
@@ -219,7 +219,7 @@
         new_env[env_var] = os.path.pathsep.join(paths)
 
     # We have to add our build directory to the python path so that
-    # our tests can find the pymonkey module.
+    # our tests can find the pydermonkey module.
     append_path('PYTHONPATH', get_lib_dir())
 
     if sys.platform == 'win32':
@@ -229,7 +229,7 @@
 
     result = subprocess.call(
         [sys.executable,
-         os.path.join("tests", "test_pymonkey.py")],
+         os.path.join("tests", "test_pydermonkey.py")],
         env = new_env
         )
 
--- a/src/context.cpp	Sun Aug 30 20:56:43 2009 -0700
+++ b/src/context.cpp	Tue Sep 01 03:07:24 2009 -0700
@@ -11,7 +11,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Pymonkey.
+ * The Original Code is Pydermonkey.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2007
@@ -43,7 +43,7 @@
 #include "jsdbgapi.h"
 #include "jsscript.h"
 
-// This is the default throw hook for pymonkey-owned JS contexts,
+// This is the default throw hook for pydermonkey-owned JS contexts,
 // when they've defined one in Python.
 static JSTrapStatus
 PYM_throwHook(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
@@ -70,7 +70,7 @@
   return JSTRAP_CONTINUE;
 }
 
-// This is the default JSOperationCallback for pymonkey-owned JS contexts,
+// This is the default JSOperationCallback for pydermonkey-owned JS contexts,
 // when they've defined one in Python.
 static JSBool
 PYM_operationCallback(JSContext *cx)
@@ -96,7 +96,7 @@
   return JS_TRUE;
 }
 
-// This is the default JSErrorReporter for pymonkey-owned JS contexts.
+// This is the default JSErrorReporter for pydermonkey-owned JS contexts.
 static void
 PYM_reportError(JSContext *cx, const char *message, JSErrorReport *report)
 {
@@ -804,7 +804,7 @@
 PyTypeObject PYM_JSContextType = {
   PyObject_HEAD_INIT(NULL)
   0,                           /*ob_size*/
-  "pymonkey.Context",          /*tp_name*/
+  "pydermonkey.Context",          /*tp_name*/
   sizeof(PYM_JSContextObject), /*tp_basicsize*/
   0,                           /*tp_itemsize*/
                                /*tp_dealloc*/
--- a/src/context.h	Sun Aug 30 20:56:43 2009 -0700
+++ b/src/context.h	Tue Sep 01 03:07:24 2009 -0700
@@ -11,7 +11,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Pymonkey.
+ * The Original Code is Pydermonkey.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2007
--- a/src/function.cpp	Sun Aug 30 20:56:43 2009 -0700
+++ b/src/function.cpp	Tue Sep 01 03:07:24 2009 -0700
@@ -11,7 +11,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Pymonkey.
+ * The Original Code is Pydermonkey.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2007
@@ -152,7 +152,7 @@
 PyTypeObject PYM_JSFunctionType = {
   PyObject_HEAD_INIT(NULL)
   0,                           /*ob_size*/
-  "pymonkey.Function",         /*tp_name*/
+  "pydermonkey.Function",         /*tp_name*/
   sizeof(PYM_JSFunction),      /*tp_basicsize*/
   0,                           /*tp_itemsize*/
                                /*tp_dealloc*/
--- a/src/function.h	Sun Aug 30 20:56:43 2009 -0700
+++ b/src/function.h	Tue Sep 01 03:07:24 2009 -0700
@@ -11,7 +11,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Pymonkey.
+ * The Original Code is Pydermonkey.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2007
--- a/src/object.cpp	Sun Aug 30 20:56:43 2009 -0700
+++ b/src/object.cpp	Tue Sep 01 03:07:24 2009 -0700
@@ -11,7 +11,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Pymonkey.
+ * The Original Code is Pydermonkey.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2007
@@ -69,7 +69,7 @@
 {
   JSClass *klass = JS_GET_CLASS(cx, obj);
   if (klass != &PYM_JS_ObjectClass) {
-    JS_ReportError(cx, "Object is not an instance of PymonkeyObject");
+    JS_ReportError(cx, "Object is not an instance of PydermonkeyObject");
     return JS_FALSE;
   }
 
@@ -93,7 +93,7 @@
 // garbage collected by the JS interpreter, it releases its reference on
 // the Python object.
 JSClass PYM_JS_ObjectClass = {
-  "PymonkeyObject", JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_PRIVATE,
+  "PydermonkeyObject", JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_PRIVATE,
   JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, PYM_JS_finalizeObject,
   JSCLASS_NO_OPTIONAL_MEMBERS
@@ -137,7 +137,7 @@
 PyTypeObject PYM_JSObjectType = {
   PyObject_HEAD_INIT(NULL)
   0,                           /*ob_size*/
-  "pymonkey.Object",           /*tp_name*/
+  "pydermonkey.Object",           /*tp_name*/
   sizeof(PYM_JSObject),        /*tp_basicsize*/
   0,                           /*tp_itemsize*/
                                /*tp_dealloc*/
@@ -246,6 +246,6 @@
   object->obj = obj;
 
   JS_AddNamedRootRT(object->runtime->rt, &object->obj,
-                    "Pymonkey-Generated Object");
+                    "Pydermonkey-Generated Object");
   return object;
 }
--- a/src/object.h	Sun Aug 30 20:56:43 2009 -0700
+++ b/src/object.h	Tue Sep 01 03:07:24 2009 -0700
@@ -11,7 +11,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Pymonkey.
+ * The Original Code is Pydermonkey.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2007
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pydermonkey.cpp	Tue Sep 01 03:07:24 2009 -0700
@@ -0,0 +1,112 @@
+/* ***** 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 Pydermonkey.
+ *
+ * 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 "undefined.h"
+#include "runtime.h"
+#include "context.h"
+#include "object.h"
+#include "function.h"
+#include "script.h"
+#include "utils.h"
+
+static PyObject *
+PYM_getDebugInfo(PyObject *self, PyObject *args)
+{
+  PyObject *info = Py_BuildValue("{sI}",
+                                 "runtime_count", PYM_getJSRuntimeCount());
+  return info;
+}
+
+static PyMethodDef PYM_methods[] = {
+  {"get_debug_info", PYM_getDebugInfo, METH_VARARGS,
+   "Get debugging information about the module."},
+  {NULL, NULL, 0, NULL}
+};
+
+PyMODINIT_FUNC
+initpydermonkey(void)
+{
+  PyObject *module;
+
+  module = Py_InitModule("pydermonkey", PYM_methods);
+  if (module == NULL)
+    return;
+
+  if (PyType_Ready(&PYM_undefinedType) < 0)
+    return;
+
+  PYM_undefined = PyObject_New(PYM_undefinedObject, &PYM_undefinedType);
+  if (PYM_undefined == NULL)
+    return;
+  Py_INCREF(PYM_undefined);
+  PyModule_AddObject(module, "undefined", (PyObject *) PYM_undefined);
+
+  PYM_error = PyErr_NewException("pydermonkey.error", NULL, NULL);
+  Py_INCREF(PYM_error);
+  PyModule_AddObject(module, "error", PYM_error);
+
+  if (!PyType_Ready(&PYM_JSRuntimeType) < 0)
+    return;
+
+  Py_INCREF(&PYM_JSRuntimeType);
+  PyModule_AddObject(module, "Runtime", (PyObject *) &PYM_JSRuntimeType);
+
+  if (!PyType_Ready(&PYM_JSContextType) < 0)
+    return;
+
+  Py_INCREF(&PYM_JSContextType);
+  PyModule_AddObject(module, "Context", (PyObject *) &PYM_JSContextType);
+
+  if (!PyType_Ready(&PYM_JSObjectType) < 0)
+    return;
+
+  Py_INCREF(&PYM_JSObjectType);
+  PyModule_AddObject(module, "Object", (PyObject *) &PYM_JSObjectType);
+
+  PYM_JSFunctionType.tp_base = &PYM_JSObjectType;
+  if (!PyType_Ready(&PYM_JSFunctionType) < 0)
+    return;
+
+  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);
+}
--- a/src/pymonkey.cpp	Sun Aug 30 20:56:43 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/* ***** 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 "undefined.h"
-#include "runtime.h"
-#include "context.h"
-#include "object.h"
-#include "function.h"
-#include "script.h"
-#include "utils.h"
-
-static PyObject *
-PYM_getDebugInfo(PyObject *self, PyObject *args)
-{
-  PyObject *info = Py_BuildValue("{sI}",
-                                 "runtime_count", PYM_getJSRuntimeCount());
-  return info;
-}
-
-static PyMethodDef PYM_methods[] = {
-  {"get_debug_info", PYM_getDebugInfo, METH_VARARGS,
-   "Get debugging information about the module."},
-  {NULL, NULL, 0, NULL}
-};
-
-PyMODINIT_FUNC
-initpymonkey(void)
-{
-  PyObject *module;
-
-  module = Py_InitModule("pymonkey", PYM_methods);
-  if (module == NULL)
-    return;
-
-  if (PyType_Ready(&PYM_undefinedType) < 0)
-    return;
-
-  PYM_undefined = PyObject_New(PYM_undefinedObject, &PYM_undefinedType);
-  if (PYM_undefined == NULL)
-    return;
-  Py_INCREF(PYM_undefined);
-  PyModule_AddObject(module, "undefined", (PyObject *) PYM_undefined);
-
-  PYM_error = PyErr_NewException("pymonkey.error", NULL, NULL);
-  Py_INCREF(PYM_error);
-  PyModule_AddObject(module, "error", PYM_error);
-
-  if (!PyType_Ready(&PYM_JSRuntimeType) < 0)
-    return;
-
-  Py_INCREF(&PYM_JSRuntimeType);
-  PyModule_AddObject(module, "Runtime", (PyObject *) &PYM_JSRuntimeType);
-
-  if (!PyType_Ready(&PYM_JSContextType) < 0)
-    return;
-
-  Py_INCREF(&PYM_JSContextType);
-  PyModule_AddObject(module, "Context", (PyObject *) &PYM_JSContextType);
-
-  if (!PyType_Ready(&PYM_JSObjectType) < 0)
-    return;
-
-  Py_INCREF(&PYM_JSObjectType);
-  PyModule_AddObject(module, "Object", (PyObject *) &PYM_JSObjectType);
-
-  PYM_JSFunctionType.tp_base = &PYM_JSObjectType;
-  if (!PyType_Ready(&PYM_JSFunctionType) < 0)
-    return;
-
-  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);
-}
--- a/src/runtime.cpp	Sun Aug 30 20:56:43 2009 -0700
+++ b/src/runtime.cpp	Tue Sep 01 03:07:24 2009 -0700
@@ -11,7 +11,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Pymonkey.
+ * The Original Code is Pydermonkey.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2007
@@ -151,7 +151,7 @@
 PyTypeObject PYM_JSRuntimeType = {
   PyObject_HEAD_INIT(NULL)
   0,                           /*ob_size*/
-  "pymonkey.Runtime",          /*tp_name*/
+  "pydermonkey.Runtime",          /*tp_name*/
   sizeof(PYM_JSRuntimeObject), /*tp_basicsize*/
   0,                           /*tp_itemsize*/
                                /*tp_dealloc*/
--- a/src/runtime.h	Sun Aug 30 20:56:43 2009 -0700
+++ b/src/runtime.h	Tue Sep 01 03:07:24 2009 -0700
@@ -11,7 +11,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Pymonkey.
+ * The Original Code is Pydermonkey.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2007
--- a/src/script.cpp	Sun Aug 30 20:56:43 2009 -0700
+++ b/src/script.cpp	Tue Sep 01 03:07:24 2009 -0700
@@ -11,7 +11,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Pymonkey.
+ * The Original Code is Pydermonkey.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2007
@@ -90,7 +90,7 @@
 PyTypeObject PYM_JSScriptType = {
   PyObject_HEAD_INIT(NULL)
   0,                           /*ob_size*/
-  "pymonkey.Script",           /*tp_name*/
+  "pydermonkey.Script",           /*tp_name*/
   sizeof(PYM_JSScript),        /*tp_basicsize*/
   0,                           /*tp_itemsize*/
                                /*tp_dealloc*/
--- a/src/script.h	Sun Aug 30 20:56:43 2009 -0700
+++ b/src/script.h	Tue Sep 01 03:07:24 2009 -0700
@@ -11,7 +11,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Pymonkey.
+ * The Original Code is Pydermonkey.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2007
--- a/src/undefined.cpp	Sun Aug 30 20:56:43 2009 -0700
+++ b/src/undefined.cpp	Tue Sep 01 03:07:24 2009 -0700
@@ -11,7 +11,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Pymonkey.
+ * The Original Code is Pydermonkey.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2007
@@ -47,13 +47,13 @@
 };
 
 static PyObject *PYM_undefinedRepr(PyObject *o) {
-  return PyString_FromString("pymonkey.undefined");
+  return PyString_FromString("pydermonkey.undefined");
 }
 
 PyTypeObject PYM_undefinedType = {
   PyObject_HEAD_INIT(NULL)
   0,                           /*ob_size*/
-  "pymonkey.undefined",        /*tp_name*/
+  "pydermonkey.undefined",        /*tp_name*/
   sizeof(PYM_undefinedObject), /*tp_basicsize*/
   0,                           /*tp_itemsize*/
   0,                           /*tp_dealloc*/
--- a/src/undefined.h	Sun Aug 30 20:56:43 2009 -0700
+++ b/src/undefined.h	Tue Sep 01 03:07:24 2009 -0700
@@ -11,7 +11,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Pymonkey.
+ * The Original Code is Pydermonkey.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2007
--- a/src/utils.cpp	Sun Aug 30 20:56:43 2009 -0700
+++ b/src/utils.cpp	Tue Sep 01 03:07:24 2009 -0700
@@ -11,7 +11,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Pymonkey.
+ * The Original Code is Pydermonkey.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2007
--- a/src/utils.h	Sun Aug 30 20:56:43 2009 -0700
+++ b/src/utils.h	Tue Sep 01 03:07:24 2009 -0700
@@ -11,7 +11,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Pymonkey.
+ * The Original Code is Pydermonkey.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2007
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test_pydermonkey.py	Tue Sep 01 03:07:24 2009 -0700
@@ -0,0 +1,830 @@
+import gc
+import sys
+import unittest
+import weakref
+import time
+import threading
+
+import pydermonkey
+
+class PydermonkeyTests(unittest.TestCase):
+    def setUp(self):
+        self._teardowns = []
+
+    def tearDown(self):
+        self.last_exception = None
+        while self._teardowns:
+            obj = self._teardowns.pop()
+            runtime = obj.get_runtime()
+            runtime.new_context().clear_object_private(obj)
+            del runtime
+            del obj
+        self.assertEqual(pydermonkey.get_debug_info()['runtime_count'], 0)
+
+    def _clearOnTeardown(self, obj):
+        self._teardowns.append(obj)
+
+    def _evaljs(self, code):
+        rt = pydermonkey.Runtime()
+        cx = rt.new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        return cx.evaluate_script(obj, code, '<string>', 1)
+
+    def _execjs(self, code):
+        rt = pydermonkey.Runtime()
+        cx = rt.new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        script = cx.compile_script(code, '<string>', 1)
+        return cx.execute_script(obj, script)
+
+    def _evalJsWrappedPyFunc(self, func, code):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        jsfunc = cx.new_function(func, func.__name__)
+        self._clearOnTeardown(jsfunc)
+        cx.define_property(obj, func.__name__, jsfunc)
+        return cx.evaluate_script(obj, code, '<string>', 1)
+
+    def assertRaises(self, exctype, func, *args):
+        was_raised = False
+        try:
+            func(*args)
+        except exctype, e:
+            self.last_exception = e
+            was_raised = True
+        self.assertTrue(was_raised)
+
+    def testSyntaxErrorsAreRaised(self):
+        for run in [self._evaljs, self._execjs]:
+            self.assertRaises(pydermonkey.error, run, '5f')
+            self.assertEqual(
+                self.last_exception.args[1],
+                u'SyntaxError: missing ; before statement'
+                )
+
+    def testGetStackOnEmptyStackReturnsNone(self):
+        cx = pydermonkey.Runtime().new_context()
+        self.assertEqual(cx.get_stack(), None)
+
+    def testGetStackWorks(self):
+        stack_holder = []
+
+        def func(cx, this, args):
+            stack_holder.append(cx.get_stack())
+
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        jsfunc = cx.new_function(func, func.__name__)
+        self._clearOnTeardown(jsfunc)
+        cx.define_property(obj, func.__name__, jsfunc)
+        cx.evaluate_script(obj, '(function closure() { \nfunc() })()',
+                           '<string>', 1)
+        stack = stack_holder[0]
+        script = stack['caller']['caller']['script']
+        pc = stack['caller']['caller']['pc']
+        closure = stack['caller']['function']
+        self.assertEqual(closure.name, 'closure')
+        self.assertEqual(closure.filename, '<string>')
+        self.assertEqual(stack['caller']['script'], None)
+        self.assertEqual(stack['caller']['lineno'], 2)
+        self.assertEqual(script.filename, '<string>')
+        self.assertEqual(stack['caller']['caller']['lineno'], 1)
+        self.assertTrue(pc >= 0 and pc < len(buffer(script)))
+        self.assertEqual(stack['caller']['caller']['caller'], None)
+
+    def testScriptHasFilenameMember(self):
+        cx = pydermonkey.Runtime().new_context()
+        script = cx.compile_script('foo', '<string>', 1)
+        self.assertEqual(script.filename, '<string>')
+
+    def testScriptHasLineInfo(self):
+        cx = pydermonkey.Runtime().new_context()
+        script = cx.compile_script('foo\nbar', '<string>', 1)
+        self.assertEqual(script.base_lineno, 1)
+        self.assertEqual(script.line_extent, 2)
+
+    def testScriptIsExposedAsBuffer(self):
+        rt = pydermonkey.Runtime()
+        cx = rt.new_context()
+        script = cx.compile_script('foo', '<string>', 1)
+        self.assertTrue(len(buffer(script)) > 0)
+
+    def testCompileScriptWorks(self):
+        self.assertEqual(self._execjs('5 + 1'), 6)
+
+    def testErrorsRaisedIncludeStrings(self):
+        self.assertRaises(pydermonkey.error, self._evaljs, 'boop()')
+        self.assertEqual(self.last_exception.args[1],
+                         u'ReferenceError: boop is not defined')
+
+    def testThreadSafetyExceptionIsRaised(self):
+        stuff = {}
+        def make_runtime():
+            stuff['rt'] = pydermonkey.Runtime()
+        thread = threading.Thread(target = make_runtime)
+        thread.start()
+        thread.join()
+        self.assertRaises(pydermonkey.error,
+                          stuff['rt'].new_context)
+        self.assertEqual(self.last_exception.args[0],
+                         'Function called from wrong thread')
+        del stuff['rt']
+
+    def testClearObjectPrivateWorks(self):
+        class Foo(object):
+            pass
+        pyobj = Foo()
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object(pyobj)
+        pyobj = weakref.ref(pyobj)
+        self.assertEqual(pyobj(), cx.get_object_private(obj))
+        cx.clear_object_private(obj)
+        self.assertEqual(cx.get_object_private(obj), None)
+        self.assertEqual(pyobj(), None)
+
+    def testGetObjectPrivateWorks(self):
+        class Foo(object):
+            pass
+        pyobj = Foo()
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object(pyobj)
+        pyobj = weakref.ref(pyobj)
+        self.assertEqual(pyobj(), cx.get_object_private(obj))
+        del obj
+        del cx
+        self.assertEqual(pyobj(), None)
+
+    def testContextSupportsCyclicGc(self):
+        def makecx():
+            cx = pydermonkey.Runtime().new_context()
+
+            def opcb(othercx):
+                return cx
+
+            cx.set_operation_callback(opcb)
+            return cx
+
+        gc.disable()
+        cx = makecx()
+        wcx = weakref.ref(cx)
+        self.assertEqual(wcx(), cx)
+        del cx
+        self.assertTrue(wcx())
+        gc.enable()
+        gc.collect()
+        self.assertEqual(wcx(), None)
+
+    def testOperationCallbackIsCalled(self):
+        def opcb(cx):
+            raise Exception("stop eet!")
+
+        cx = pydermonkey.Runtime().new_context()
+        cx.set_operation_callback(opcb)
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+
+        def watchdog():
+            time.sleep(0.1)
+            cx.trigger_operation_callback()
+
+        thread = threading.Thread(target = watchdog)
+        thread.start()
+
+        self.assertRaises(
+            pydermonkey.error,
+            cx.evaluate_script,
+            obj, 'while (1) {}', '<string>', 1
+            )
+
+    def testUndefinedStrIsUndefined(self):
+        self.assertEqual(str(pydermonkey.undefined),
+                         "pydermonkey.undefined")
+
+    def testScriptedJsFuncHasIsPythonFalse(self):
+        cx = pydermonkey.Runtime().new_context()
+        jsfunc = cx.evaluate_script(cx.new_object(), 
+                                    '(function(){})', '<string>', 1)
+        self.assertFalse(jsfunc.is_python)
+
+    def testJsWrappedPythonFuncHasIsPythonTrue(self):
+        def foo(cx, this, args):
+            pass
+
+        cx = pydermonkey.Runtime().new_context()
+        jsfunc = cx.new_function(foo, foo.__name__)
+        self.assertTrue(jsfunc.is_python)
+
+    def testJsWrappedPythonFuncHasNoFilename(self):
+        def foo(cx, this, args):
+            pass
+
+        cx = pydermonkey.Runtime().new_context()
+        jsfunc = cx.new_function(foo, foo.__name__)
+        self.assertEqual(jsfunc.filename, None)
+
+    def testJsScriptedFuncHasNoPrivate(self):
+        cx = pydermonkey.Runtime().new_context()
+        jsfunc = cx.evaluate_script(cx.new_object(),
+                                    '(function(){})', '<string>', 1)
+        self.assertEqual(cx.get_object_private(jsfunc), None)
+
+    def testGetPendingExceptionReturnsNone(self):
+        cx = pydermonkey.Runtime().new_context()
+        self.assertFalse(cx.is_exception_pending())
+        self.assertEqual(cx.get_pending_exception(), None)
+
+    def testThrowHookWorks(self):
+        exceptions = []
+        def throwhook(cx):
+            self.assertTrue(cx.is_exception_pending())
+            exceptions.append(cx.get_pending_exception())
+
+        cx = pydermonkey.Runtime().new_context()
+        cx.set_throw_hook(throwhook)
+        self.assertRaises(
+            pydermonkey.error,
+            cx.evaluate_script,
+            cx.new_object(),
+            '(function() { throw "hi"; })()',
+            '<string>', 1
+            )
+        self.assertEqual(exceptions, ['hi', 'hi'])
+        self.assertFalse(cx.is_exception_pending())
+        self.assertEqual(cx.get_pending_exception(), None)
+
+    def testJsWrappedPythonFuncHasPrivate(self):
+        def foo(cx, this, args):
+            pass
+
+        cx = pydermonkey.Runtime().new_context()
+        jsfunc = cx.new_function(foo, foo.__name__)
+        self.assertEqual(cx.get_object_private(jsfunc), foo)
+
+    def testJsWrappedPythonFuncIsNotGCd(self):
+        def define(cx, obj):
+            def func(cx, this, args):
+                return u'func was called'
+            jsfunc = cx.new_function(func, func.__name__)
+            cx.define_property(obj, func.__name__, jsfunc)
+            return weakref.ref(func)
+        rt = pydermonkey.Runtime()
+        cx = rt.new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        ref = define(cx, obj)
+        cx.gc()
+        self.assertNotEqual(ref(), None)
+        result = cx.evaluate_script(obj, 'func()', '<string>', 1)
+        self.assertEqual(result, u'func was called')
+
+        # Now ensure that the wrapped function is GC'd when it's
+        # no longer reachable from JS space.
+        cx.define_property(obj, 'func', 0)
+        cx.gc()
+        self.assertEqual(ref(), None)
+
+    def testCircularJsWrappedPythonFuncIsGCdIfPrivateCleared(self):
+        def define(cx, obj):
+            rt = cx.get_runtime()
+            def func(cx, this, args):
+                # Oh noes, a circular reference is born!
+                rt
+            jsfunc = cx.new_function(func, func.__name__)
+            cx.define_property(obj, func.__name__, jsfunc)
+            return (jsfunc, weakref.ref(func))
+        rt = pydermonkey.Runtime()
+        cx = rt.new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        jsfunc, ref = define(cx, obj)
+
+        # This will break the circular reference.
+        cx.clear_object_private(jsfunc)
+
+        del jsfunc
+        del rt
+        del cx
+        del obj
+        self.assertEqual(ref(), None)
+
+    def testFunctionsWithClosuresAreNotIdentical(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        cx.evaluate_script(
+            obj, "function build(x) { return function foo() { return x; } }",
+            "<string>", 1
+            )
+        func1 = cx.evaluate_script(obj, "build(1)", "<string>", 1)
+        func2 = cx.evaluate_script(obj, "build(2)", "<string>", 1)
+        self.assertNotEqual(func1, func2)
+        self.assertEqual(func1.name, 'foo')
+        self.assertEqual(func1.name, func2.name)
+
+    def testAnonymousJsFunctionHasNullNameAttribute(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        jsfunc = cx.evaluate_script(obj, "(function() {})",
+                                    "<string>", 1)
+        self.assertEqual(jsfunc.name, None)
+
+    def testJsFunctionHasNameAttribute(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        jsfunc = cx.evaluate_script(obj, "(function blarg() {})",
+                                    "<string>", 1)
+        self.assertEqual(jsfunc.name, "blarg")
+
+    def testJsWrappedPythonFuncHasNameAttribute(self):
+        def func(cx, this, args):
+            return True
+
+        cx = pydermonkey.Runtime().new_context()
+        jsfunc = cx.new_function(func, "foo")
+        self.assertEqual(jsfunc.name, "foo")
+
+    def testJsWrappedPythonFuncIsGCdAtRuntimeDestruction(self):
+        def define(cx, obj):
+            def func(cx, this, args):
+                return u'func was called'
+            jsfunc = cx.new_function(func, func.__name__)
+            cx.define_property(obj, func.__name__, jsfunc)
+            return weakref.ref(func)
+        rt = pydermonkey.Runtime()
+        cx = rt.new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        ref = define(cx, obj)
+        del rt
+        del cx
+        del obj
+        self.assertEqual(ref(), None)
+
+    def testJsWrappedPythonFuncThrowsExcIfPrivateCleared(self):
+        def func(cx, this, args):
+            return True
+
+        code = "func()"
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        jsfunc = cx.new_function(func, func.__name__)
+        cx.define_property(obj, func.__name__, jsfunc)
+        cx.clear_object_private(jsfunc)
+        self.assertRaises(pydermonkey.error,
+                          cx.evaluate_script,
+                          obj, code, '<string>', 1)
+        self.assertEqual(
+            self._tostring(cx, self.last_exception.args[0]),
+            "Error: Wrapped Python function no longer exists"
+            )
+
+    def testJsWrappedPythonFuncPassesContext(self):
+        contexts = []
+
+        def func(cx, this, args):
+            contexts.append(cx)
+            return True
+
+        code = "func()"
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        jsfunc = cx.new_function(func, func.__name__)
+        self._clearOnTeardown(jsfunc)
+        cx.define_property(obj, func.__name__, jsfunc)
+        cx.evaluate_script(obj, code, '<string>', 1)
+        self.assertEqual(contexts[0], cx)
+
+    def testJsWrappedPythonFuncPassesThisArg(self):
+        thisObjs = []
+
+        def func(cx, this, args):
+            thisObjs.append(this)
+            return True
+
+        code = "func()"
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        jsfunc = cx.new_function(func, func.__name__)
+        self._clearOnTeardown(jsfunc)
+        cx.define_property(obj, func.__name__, jsfunc)
+        cx.evaluate_script(obj, code, '<string>', 1)
+        self.assertEqual(thisObjs[0], obj)
+
+    def testJsWrappedPythonFuncPassesFuncArgs(self):
+        funcArgs = []
+
+        def func(cx, this, args):
+            funcArgs.append(args)
+            return True
+
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        jsfunc = cx.new_function(func, func.__name__)
+        self._clearOnTeardown(jsfunc)
+
+        cx.define_property(obj, func.__name__, jsfunc)
+
+        cx.evaluate_script(obj, "func()", '<string>', 1)
+        self.assertEqual(len(funcArgs[0]), 0)
+        self.assertTrue(isinstance(funcArgs[0], tuple))
+
+        cx.evaluate_script(obj, "func(1, 'foo')", '<string>', 1)
+        self.assertEqual(len(funcArgs[1]), 2)
+        self.assertEqual(funcArgs[1][0], 1)
+        self.assertEqual(funcArgs[1][1], u'foo')
+
+    def testJsWrappedPythonFunctionReturnsUnicodeWithEmbeddedNULs(self):
+        def hai2u(cx, this, args):
+            return args[0] + u"o hai"
+        self.assertEqual(self._evalJsWrappedPyFunc(hai2u,
+                                                   'hai2u("blah\x00 ")'),
+                         u"blah\x00 o hai")
+
+    def testJsWrappedPythonFunctionReturnsString(self):
+        def hai2u(cx, this, args):
+            return "o hai"
+        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
+                         "o hai")
+
+    def testJsWrappedPythonFunctionReturnsUnicode(self):
+        def hai2u(cx, this, args):
+            return u"o hai\u2026"
+        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
+                         u"o hai\u2026")
+
+    def testJsWrappedPythonFunctionThrowsJsException(self):
+        def hai2u(cx, this, args):
+            raise pydermonkey.error(u"blarg")
+        self.assertRaises(pydermonkey.error,
+                          self._evalJsWrappedPyFunc,
+                          hai2u, 'hai2u()')
+        self.assertEqual(self.last_exception.args[0], u"blarg")
+
+    def testJsWrappedPythonFunctionThrowsPyException(self):
+        thecx = []
+        def hai2u(cx, this, args):
+            thecx.append(cx)
+            raise Exception("hello")
+        self.assertRaises(pydermonkey.error,
+                          self._evalJsWrappedPyFunc,
+                          hai2u, 'hai2u()')
+        exc = thecx[0].get_object_private(self.last_exception.args[0])
+        self.assertEqual(exc.args[0], "hello")
+
+    def testJsWrappedPythonFunctionReturnsNone(self):
+        def hai2u(cx, this, args):
+            pass
+        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
+                         None)
+
+    def testJsWrappedPythonFunctionReturnsTrue(self):
+        def hai2u(cx, this, args):
+            return True
+        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
+                         True)
+
+    def testJsWrappedPythonFunctionReturnsFalse(self):
+        def hai2u(cx, this, args):
+            return False
+        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
+                         False)
+
+    def testJsWrappedPythonFunctionReturnsSmallInt(self):
+        def hai2u(cx, this, args):
+            return 5
+        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
+                         5)
+
+    def testJsWrappedPythonFunctionReturnsFloat(self):
+        def hai2u(cx, this, args):
+            return 5.1
+        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
+                         5.1)
+
+    def testJsWrappedPythonFunctionReturnsNegativeInt(self):
+        def hai2u(cx, this, args):
+            return -5
+        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
+                         -5)
+
+    def testJsWrappedPythonFunctionReturnsBigInt(self):
+        def hai2u(cx, this, args):
+            return 2147483647
+        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
+                         2147483647)
+
+    def testHasPropertyWorks(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        foo = cx.new_object()
+        cx.define_property(obj, u"foo\u2026", foo)
+        self.assertTrue(cx.has_property(obj, u"foo\u2026"))
+        self.assertFalse(cx.has_property(obj, "bar"))
+
+    def testDefinePropertyWorksWithUnicodePropertyNames(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        foo = cx.new_object()
+        cx.define_property(obj, u"foo\u2026", foo)
+        self.assertEqual(
+            cx.get_property(obj, u"foo\u2026"),
+            foo
+            )
+
+    def testDefinePropertyWorksWithObject(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        foo = cx.new_object()
+        cx.define_property(obj, "foo", foo)
+        self.assertEqual(
+            cx.evaluate_script(obj, 'foo', '<string>', 1),
+            foo
+            )
+
+    def testDefinePropertyWorksWithString(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        foo = cx.new_object()
+        cx.define_property(obj, "foo", u"hello")
+        self.assertEqual(
+            cx.evaluate_script(obj, 'foo', '<string>', 1),
+            u"hello"
+            )
+
+    def testObjectIsIdentityPreserving(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        cx.evaluate_script(obj, 'var foo = {bar: 1}', '<string>', 1)
+        self.assertTrue(isinstance(cx.get_property(obj, u"foo"),
+                                   pydermonkey.Object))
+        self.assertTrue(cx.get_property(obj, u"foo") is
+                        cx.get_property(obj, "foo"))
+
+    def testObjectGetattrThrowsException(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        result = cx.evaluate_script(obj, '({get foo() { throw "blah"; }})',
+                                    '<string>', 1)
+        self.assertRaises(pydermonkey.error,
+                          cx.get_property,
+                          result,
+                          u"foo")
+        self.assertEqual(self.last_exception.args[0], u"blah")
+
+    def testInfiniteRecursionRaisesError(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        self.assertRaises(
+            pydermonkey.error,
+            cx.evaluate_script,
+            obj, '(function foo() { foo(); })();', '<string>', 1
+            )
+        self.assertEqual(
+            self._tostring(cx, self.last_exception.args[0]),
+            "InternalError: too much recursion"
+            )
+
+    def testObjectGetattrWorks(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        cx.evaluate_script(obj, 'var boop = 5', '<string>', 1)
+        cx.evaluate_script(obj, 'this["blarg\u2026"] = 5', '<string>', 1)
+        self.assertEqual(cx.get_property(obj, u"beans"),
+                         pydermonkey.undefined)
+        self.assertEqual(cx.get_property(obj, u"blarg\u2026"), 5)
+        self.assertEqual(cx.get_property(obj, u"boop"), 5)
+
+    def testContextIsInstance(self):
+        cx = pydermonkey.Runtime().new_context()
+        self.assertTrue(isinstance(cx, pydermonkey.Context))
+
+    def testContextTypeCannotBeInstantiated(self):
+        self.assertRaises(TypeError, pydermonkey.Context)
+
+    def testObjectIsInstance(self):
+        obj = pydermonkey.Runtime().new_context().new_object()
+        self.assertTrue(isinstance(obj, pydermonkey.Object))
+        self.assertFalse(isinstance(obj, pydermonkey.Function))
+
+    def testObjectTypeCannotBeInstantiated(self):
+        self.assertRaises(TypeError, pydermonkey.Object)
+
+    def testFunctionIsInstance(self):
+        def boop():
+            pass
+        obj = pydermonkey.Runtime().new_context().new_function(boop, "boop")
+        self.assertTrue(isinstance(obj, pydermonkey.Object))
+        self.assertTrue(isinstance(obj, pydermonkey.Function))
+
+    def testFunctionTypeCannotBeInstantiated(self):
+        self.assertRaises(TypeError, pydermonkey.Function)
+
+    def testObjectGetRuntimeWorks(self):
+        rt = pydermonkey.Runtime()
+        obj = rt.new_context().new_object()
+        self.assertEqual(obj.get_runtime(), rt)
+
+    def testContextGetRuntimeWorks(self):
+        rt = pydermonkey.Runtime()
+        cx = rt.new_context()
+        self.assertEqual(cx.get_runtime(), rt)
+
+    def testRuntimesAreWeakReferencable(self):
+        rt = pydermonkey.Runtime()
+        wrt = weakref.ref(rt)
+        self.assertEqual(rt, wrt())
+        del rt
+        self.assertEqual(wrt(), None)
+
+    def testContextsAreWeakReferencable(self):
+        rt = pydermonkey.Runtime()
+        cx = rt.new_context()
+        wcx = weakref.ref(cx)
+        self.assertEqual(cx, wcx())
+        del cx
+        self.assertEqual(wcx(), None)
+
+    def testUndefinedCannotBeInstantiated(self):
+        self.assertRaises(TypeError, pydermonkey.undefined)
+
+    def testEvaluateThrowsException(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        self.assertRaises(pydermonkey.error,
+                          cx.evaluate_script,
+                          obj, 'hai2u()', '<string>', 1)
+        self.assertEqual(self._tostring(cx,
+                                        self.last_exception.args[0]),
+                         'ReferenceError: hai2u is not defined')
+
+    def testThrowingObjWithBadToStringWorks(self):
+        self.assertRaises(
+            pydermonkey.error,
+            self._evaljs,
+            "throw {toString: function() { throw 'dujg' }}"
+            )
+        self.assertEqual(
+            self.last_exception.args[1],
+            "<string conversion failed>"
+            )
+
+    def testEvaluateTakesUnicodeCode(self):
+        self.assertEqual(self._evaljs(u"'foo\u2026'"),
+                         u"foo\u2026")
+
+    def testEvaluateReturnsUndefined(self):
+        retval = self._evaljs("")
+        self.assertTrue(retval is pydermonkey.undefined)
+
+    def testEvaludateReturnsUnicodeWithEmbeddedNULs(self):
+        retval = self._evaljs("'\x00hi'")
+        self.assertEqual(retval, u'\x00hi')
+
+    def testEvaluateReturnsSMPUnicode(self):
+        # This is 'LINEAR B SYLLABLE B008 A', in the supplementary
+        # multilingual plane (SMP).
+        retval = self._evaljs("'\uD800\uDC00'")
+        self.assertEqual(retval, u'\U00010000')
+        self.assertEqual(retval.encode('utf-16'),
+                         '\xff\xfe\x00\xd8\x00\xdc')
+
+    def testEvaluateReturnsBMPUnicode(self):
+        retval = self._evaljs("'o hai\u2026'")
+        self.assertTrue(type(retval) == unicode)
+        self.assertEqual(retval, u'o hai\u2026')
+
+    def testEvaluateReturnsObject(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        obj = cx.evaluate_script(obj, '({boop: 1})', '<string>', 1)
+        self.assertTrue(isinstance(obj, pydermonkey.Object))
+        self.assertEqual(cx.get_property(obj, u"boop"), 1)
+
+    def testScriptedFunctionsHaveFilenameInfo(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        jsfunc = cx.evaluate_script(obj,
+                                    '(function boop() { \nreturn 1; })',
+                                    'somefile', 5)
+        self.assertEqual(jsfunc.filename, 'somefile')
+        self.assertEqual(jsfunc.base_lineno, 5)
+        self.assertEqual(jsfunc.line_extent, 2)
+
+    def testEvaluateReturnsFunction(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        obj = cx.evaluate_script(obj, '(function boop() { return 1; })',
+                                 '<string>', 1)
+        self.assertTrue(isinstance(obj, pydermonkey.Function))
+
+    def testJsExceptionStateIsClearedAfterExceptionIsCaught(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        self.assertRaises(pydermonkey.error,
+                          cx.evaluate_script,
+                          obj, 'blah()', '<string>', 1)
+        self.assertEqual(cx.evaluate_script(obj, '5+3', '<string>', 1),
+                         8)
+
+    def testCallFunctionRaisesErrorOnBadFuncArgs(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        obj = cx.evaluate_script(
+            obj,
+            '(function boop(a, b) { return a+b+this.c; })',
+            '<string>', 1
+            )
+        self.assertRaises(
+            NotImplementedError,
+            cx.call_function,
+            obj, obj, (1, self)
+            )
+
+    def _tostring(self, cx, obj):
+        return cx.call_function(obj,
+                                cx.get_property(obj, u"toString"),
+                                ())
+
+    def testCallFunctionRaisesErrorFromJS(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        obj = cx.evaluate_script(
+            obj,
+            '(function boop(a, b) { blarg(); })',
+            '<string>', 1
+            )
+        self.assertRaises(pydermonkey.error,
+                          cx.call_function,
+                          obj, obj, (1,))
+        self.assertEqual(self._tostring(cx,
+                                        self.last_exception.args[0]),
+                         'ReferenceError: blarg is not defined')
+
+    def testInitStandardClassesRaisesExcOnRuntimeMismatch(self):
+        cx2 = pydermonkey.Runtime().new_context()
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        self.assertRaises(ValueError,
+                          cx2.init_standard_classes,
+                          obj)
+        self.assertEqual(self.last_exception.args[0],
+                         'JS runtime mismatch')
+
+    def testCallFunctionWorks(self):
+        cx = pydermonkey.Runtime().new_context()
+        obj = cx.new_object()
+        thisArg = cx.new_object()
+        cx.define_property(thisArg, "c", 3)
+        cx.init_standard_classes(obj)
+        obj = cx.evaluate_script(
+            obj,
+            '(function boop(a, b) { return a+b+this.c; })',
+            '<string>', 1
+            )
+        self.assertEqual(cx.call_function(thisArg, obj, (1,2)), 6)
+
+    def testEvaluateReturnsTrue(self):
+        self.assertTrue(self._evaljs('true') is True)
+
+    def testEvaluateReturnsFalse(self):
+        self.assertTrue(self._evaljs('false') is False)
+
+    def testEvaluateReturnsNone(self):
+        self.assertTrue(self._evaljs('null') is None)
+
+    def testEvaluateReturnsIntegers(self):
+        self.assertEqual(self._evaljs('1+3'), 4)
+
+    def testEvaluateReturnsNegativeIntegers(self):
+        self.assertEqual(self._evaljs('-5'), -5)
+
+    def testEvaluateReturnsBigIntegers(self):
+        self.assertEqual(self._evaljs('2147483647*2'),
+                         2147483647*2)
+
+    def testEvaluateReturnsFloats(self):
+        self.assertEqual(self._evaljs('1.1+3'), 4.1)
+
+if __name__ == '__main__':
+    unittest.main()
--- a/tests/test_pymonkey.py	Sun Aug 30 20:56:43 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,830 +0,0 @@
-import gc
-import sys
-import unittest
-import weakref
-import time
-import threading
-
-import pymonkey
-
-class PymonkeyTests(unittest.TestCase):
-    def setUp(self):
-        self._teardowns = []
-
-    def tearDown(self):
-        self.last_exception = None
-        while self._teardowns:
-            obj = self._teardowns.pop()
-            runtime = obj.get_runtime()
-            runtime.new_context().clear_object_private(obj)
-            del runtime
-            del obj
-        self.assertEqual(pymonkey.get_debug_info()['runtime_count'], 0)
-
-    def _clearOnTeardown(self, obj):
-        self._teardowns.append(obj)
-
-    def _evaljs(self, code):
-        rt = pymonkey.Runtime()
-        cx = rt.new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        return cx.evaluate_script(obj, code, '<string>', 1)
-
-    def _execjs(self, code):
-        rt = pymonkey.Runtime()
-        cx = rt.new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        script = cx.compile_script(code, '<string>', 1)
-        return cx.execute_script(obj, script)
-
-    def _evalJsWrappedPyFunc(self, func, code):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        jsfunc = cx.new_function(func, func.__name__)
-        self._clearOnTeardown(jsfunc)
-        cx.define_property(obj, func.__name__, jsfunc)
-        return cx.evaluate_script(obj, code, '<string>', 1)
-
-    def assertRaises(self, exctype, func, *args):
-        was_raised = False
-        try:
-            func(*args)
-        except exctype, e:
-            self.last_exception = e
-            was_raised = True
-        self.assertTrue(was_raised)
-
-    def testSyntaxErrorsAreRaised(self):
-        for run in [self._evaljs, self._execjs]:
-            self.assertRaises(pymonkey.error, run, '5f')
-            self.assertEqual(
-                self.last_exception.args[1],
-                u'SyntaxError: missing ; before statement'
-                )
-
-    def testGetStackOnEmptyStackReturnsNone(self):
-        cx = pymonkey.Runtime().new_context()
-        self.assertEqual(cx.get_stack(), None)
-
-    def testGetStackWorks(self):
-        stack_holder = []
-
-        def func(cx, this, args):
-            stack_holder.append(cx.get_stack())
-
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        jsfunc = cx.new_function(func, func.__name__)
-        self._clearOnTeardown(jsfunc)
-        cx.define_property(obj, func.__name__, jsfunc)
-        cx.evaluate_script(obj, '(function closure() { \nfunc() })()',
-                           '<string>', 1)
-        stack = stack_holder[0]
-        script = stack['caller']['caller']['script']
-        pc = stack['caller']['caller']['pc']
-        closure = stack['caller']['function']
-        self.assertEqual(closure.name, 'closure')
-        self.assertEqual(closure.filename, '<string>')
-        self.assertEqual(stack['caller']['script'], None)
-        self.assertEqual(stack['caller']['lineno'], 2)
-        self.assertEqual(script.filename, '<string>')
-        self.assertEqual(stack['caller']['caller']['lineno'], 1)
-        self.assertTrue(pc >= 0 and pc < len(buffer(script)))
-        self.assertEqual(stack['caller']['caller']['caller'], None)
-
-    def testScriptHasFilenameMember(self):
-        cx = pymonkey.Runtime().new_context()
-        script = cx.compile_script('foo', '<string>', 1)
-        self.assertEqual(script.filename, '<string>')
-
-    def testScriptHasLineInfo(self):
-        cx = pymonkey.Runtime().new_context()
-        script = cx.compile_script('foo\nbar', '<string>', 1)
-        self.assertEqual(script.base_lineno, 1)
-        self.assertEqual(script.line_extent, 2)
-
-    def testScriptIsExposedAsBuffer(self):
-        rt = pymonkey.Runtime()
-        cx = rt.new_context()
-        script = cx.compile_script('foo', '<string>', 1)
-        self.assertTrue(len(buffer(script)) > 0)
-
-    def testCompileScriptWorks(self):
-        self.assertEqual(self._execjs('5 + 1'), 6)
-
-    def testErrorsRaisedIncludeStrings(self):
-        self.assertRaises(pymonkey.error, self._evaljs, 'boop()')
-        self.assertEqual(self.last_exception.args[1],
-                         u'ReferenceError: boop is not defined')
-
-    def testThreadSafetyExceptionIsRaised(self):
-        stuff = {}
-        def make_runtime():
-            stuff['rt'] = pymonkey.Runtime()
-        thread = threading.Thread(target = make_runtime)
-        thread.start()
-        thread.join()
-        self.assertRaises(pymonkey.error,
-                          stuff['rt'].new_context)
-        self.assertEqual(self.last_exception.args[0],
-                         'Function called from wrong thread')
-        del stuff['rt']
-
-    def testClearObjectPrivateWorks(self):
-        class Foo(object):
-            pass
-        pyobj = Foo()
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object(pyobj)
-        pyobj = weakref.ref(pyobj)
-        self.assertEqual(pyobj(), cx.get_object_private(obj))
-        cx.clear_object_private(obj)
-        self.assertEqual(cx.get_object_private(obj), None)
-        self.assertEqual(pyobj(), None)
-
-    def testGetObjectPrivateWorks(self):
-        class Foo(object):
-            pass
-        pyobj = Foo()
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object(pyobj)
-        pyobj = weakref.ref(pyobj)
-        self.assertEqual(pyobj(), cx.get_object_private(obj))
-        del obj
-        del cx
-        self.assertEqual(pyobj(), None)
-
-    def testContextSupportsCyclicGc(self):
-        def makecx():
-            cx = pymonkey.Runtime().new_context()
-
-            def opcb(othercx):
-                return cx
-
-            cx.set_operation_callback(opcb)
-            return cx
-
-        gc.disable()
-        cx = makecx()
-        wcx = weakref.ref(cx)
-        self.assertEqual(wcx(), cx)
-        del cx
-        self.assertTrue(wcx())
-        gc.enable()
-        gc.collect()
-        self.assertEqual(wcx(), None)
-
-    def testOperationCallbackIsCalled(self):
-        def opcb(cx):
-            raise Exception("stop eet!")
-
-        cx = pymonkey.Runtime().new_context()
-        cx.set_operation_callback(opcb)
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-
-        def watchdog():
-            time.sleep(0.1)
-            cx.trigger_operation_callback()
-
-        thread = threading.Thread(target = watchdog)
-        thread.start()
-
-        self.assertRaises(
-            pymonkey.error,
-            cx.evaluate_script,
-            obj, 'while (1) {}', '<string>', 1
-            )
-
-    def testUndefinedStrIsUndefined(self):
-        self.assertEqual(str(pymonkey.undefined),
-                         "pymonkey.undefined")
-
-    def testScriptedJsFuncHasIsPythonFalse(self):
-        cx = pymonkey.Runtime().new_context()
-        jsfunc = cx.evaluate_script(cx.new_object(), 
-                                    '(function(){})', '<string>', 1)
-        self.assertFalse(jsfunc.is_python)
-
-    def testJsWrappedPythonFuncHasIsPythonTrue(self):
-        def foo(cx, this, args):
-            pass
-
-        cx = pymonkey.Runtime().new_context()
-        jsfunc = cx.new_function(foo, foo.__name__)
-        self.assertTrue(jsfunc.is_python)
-
-    def testJsWrappedPythonFuncHasNoFilename(self):
-        def foo(cx, this, args):
-            pass
-
-        cx = pymonkey.Runtime().new_context()
-        jsfunc = cx.new_function(foo, foo.__name__)
-        self.assertEqual(jsfunc.filename, None)
-
-    def testJsScriptedFuncHasNoPrivate(self):
-        cx = pymonkey.Runtime().new_context()
-        jsfunc = cx.evaluate_script(cx.new_object(),
-                                    '(function(){})', '<string>', 1)
-        self.assertEqual(cx.get_object_private(jsfunc), None)
-
-    def testGetPendingExceptionReturnsNone(self):
-        cx = pymonkey.Runtime().new_context()
-        self.assertFalse(cx.is_exception_pending())
-        self.assertEqual(cx.get_pending_exception(), None)
-
-    def testThrowHookWorks(self):
-        exceptions = []
-        def throwhook(cx):
-            self.assertTrue(cx.is_exception_pending())
-            exceptions.append(cx.get_pending_exception())
-
-        cx = pymonkey.Runtime().new_context()
-        cx.set_throw_hook(throwhook)
-        self.assertRaises(
-            pymonkey.error,
-            cx.evaluate_script,
-            cx.new_object(),
-            '(function() { throw "hi"; })()',
-            '<string>', 1
-            )
-        self.assertEqual(exceptions, ['hi', 'hi'])
-        self.assertFalse(cx.is_exception_pending())
-        self.assertEqual(cx.get_pending_exception(), None)
-
-    def testJsWrappedPythonFuncHasPrivate(self):
-        def foo(cx, this, args):
-            pass
-
-        cx = pymonkey.Runtime().new_context()
-        jsfunc = cx.new_function(foo, foo.__name__)
-        self.assertEqual(cx.get_object_private(jsfunc), foo)
-
-    def testJsWrappedPythonFuncIsNotGCd(self):
-        def define(cx, obj):
-            def func(cx, this, args):
-                return u'func was called'
-            jsfunc = cx.new_function(func, func.__name__)
-            cx.define_property(obj, func.__name__, jsfunc)
-            return weakref.ref(func)
-        rt = pymonkey.Runtime()
-        cx = rt.new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        ref = define(cx, obj)
-        cx.gc()
-        self.assertNotEqual(ref(), None)
-        result = cx.evaluate_script(obj, 'func()', '<string>', 1)
-        self.assertEqual(result, u'func was called')
-
-        # Now ensure that the wrapped function is GC'd when it's
-        # no longer reachable from JS space.
-        cx.define_property(obj, 'func', 0)
-        cx.gc()
-        self.assertEqual(ref(), None)
-
-    def testCircularJsWrappedPythonFuncIsGCdIfPrivateCleared(self):
-        def define(cx, obj):
-            rt = cx.get_runtime()
-            def func(cx, this, args):
-                # Oh noes, a circular reference is born!
-                rt
-            jsfunc = cx.new_function(func, func.__name__)
-            cx.define_property(obj, func.__name__, jsfunc)
-            return (jsfunc, weakref.ref(func))
-        rt = pymonkey.Runtime()
-        cx = rt.new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        jsfunc, ref = define(cx, obj)
-
-        # This will break the circular reference.
-        cx.clear_object_private(jsfunc)
-
-        del jsfunc
-        del rt
-        del cx
-        del obj
-        self.assertEqual(ref(), None)
-
-    def testFunctionsWithClosuresAreNotIdentical(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        cx.evaluate_script(
-            obj, "function build(x) { return function foo() { return x; } }",
-            "<string>", 1
-            )
-        func1 = cx.evaluate_script(obj, "build(1)", "<string>", 1)
-        func2 = cx.evaluate_script(obj, "build(2)", "<string>", 1)
-        self.assertNotEqual(func1, func2)
-        self.assertEqual(func1.name, 'foo')
-        self.assertEqual(func1.name, func2.name)
-
-    def testAnonymousJsFunctionHasNullNameAttribute(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        jsfunc = cx.evaluate_script(obj, "(function() {})",
-                                    "<string>", 1)
-        self.assertEqual(jsfunc.name, None)
-
-    def testJsFunctionHasNameAttribute(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        jsfunc = cx.evaluate_script(obj, "(function blarg() {})",
-                                    "<string>", 1)
-        self.assertEqual(jsfunc.name, "blarg")
-
-    def testJsWrappedPythonFuncHasNameAttribute(self):
-        def func(cx, this, args):
-            return True
-
-        cx = pymonkey.Runtime().new_context()
-        jsfunc = cx.new_function(func, "foo")
-        self.assertEqual(jsfunc.name, "foo")
-
-    def testJsWrappedPythonFuncIsGCdAtRuntimeDestruction(self):
-        def define(cx, obj):
-            def func(cx, this, args):
-                return u'func was called'
-            jsfunc = cx.new_function(func, func.__name__)
-            cx.define_property(obj, func.__name__, jsfunc)
-            return weakref.ref(func)
-        rt = pymonkey.Runtime()
-        cx = rt.new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        ref = define(cx, obj)
-        del rt
-        del cx
-        del obj
-        self.assertEqual(ref(), None)
-
-    def testJsWrappedPythonFuncThrowsExcIfPrivateCleared(self):
-        def func(cx, this, args):
-            return True
-
-        code = "func()"
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        jsfunc = cx.new_function(func, func.__name__)
-        cx.define_property(obj, func.__name__, jsfunc)
-        cx.clear_object_private(jsfunc)
-        self.assertRaises(pymonkey.error,
-                          cx.evaluate_script,
-                          obj, code, '<string>', 1)
-        self.assertEqual(
-            self._tostring(cx, self.last_exception.args[0]),
-            "Error: Wrapped Python function no longer exists"
-            )
-
-    def testJsWrappedPythonFuncPassesContext(self):
-        contexts = []
-
-        def func(cx, this, args):
-            contexts.append(cx)
-            return True
-
-        code = "func()"
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        jsfunc = cx.new_function(func, func.__name__)
-        self._clearOnTeardown(jsfunc)
-        cx.define_property(obj, func.__name__, jsfunc)
-        cx.evaluate_script(obj, code, '<string>', 1)
-        self.assertEqual(contexts[0], cx)
-
-    def testJsWrappedPythonFuncPassesThisArg(self):
-        thisObjs = []
-
-        def func(cx, this, args):
-            thisObjs.append(this)
-            return True
-
-        code = "func()"
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        jsfunc = cx.new_function(func, func.__name__)
-        self._clearOnTeardown(jsfunc)
-        cx.define_property(obj, func.__name__, jsfunc)
-        cx.evaluate_script(obj, code, '<string>', 1)
-        self.assertEqual(thisObjs[0], obj)
-
-    def testJsWrappedPythonFuncPassesFuncArgs(self):
-        funcArgs = []
-
-        def func(cx, this, args):
-            funcArgs.append(args)
-            return True
-
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        jsfunc = cx.new_function(func, func.__name__)
-        self._clearOnTeardown(jsfunc)
-
-        cx.define_property(obj, func.__name__, jsfunc)
-
-        cx.evaluate_script(obj, "func()", '<string>', 1)
-        self.assertEqual(len(funcArgs[0]), 0)
-        self.assertTrue(isinstance(funcArgs[0], tuple))
-
-        cx.evaluate_script(obj, "func(1, 'foo')", '<string>', 1)
-        self.assertEqual(len(funcArgs[1]), 2)
-        self.assertEqual(funcArgs[1][0], 1)
-        self.assertEqual(funcArgs[1][1], u'foo')
-
-    def testJsWrappedPythonFunctionReturnsUnicodeWithEmbeddedNULs(self):
-        def hai2u(cx, this, args):
-            return args[0] + u"o hai"
-        self.assertEqual(self._evalJsWrappedPyFunc(hai2u,
-                                                   'hai2u("blah\x00 ")'),
-                         u"blah\x00 o hai")
-
-    def testJsWrappedPythonFunctionReturnsString(self):
-        def hai2u(cx, this, args):
-            return "o hai"
-        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
-                         "o hai")
-
-    def testJsWrappedPythonFunctionReturnsUnicode(self):
-        def hai2u(cx, this, args):
-            return u"o hai\u2026"
-        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
-                         u"o hai\u2026")
-
-    def testJsWrappedPythonFunctionThrowsJsException(self):
-        def hai2u(cx, this, args):
-            raise pymonkey.error(u"blarg")
-        self.assertRaises(pymonkey.error,
-                          self._evalJsWrappedPyFunc,
-                          hai2u, 'hai2u()')
-        self.assertEqual(self.last_exception.args[0], u"blarg")
-
-    def testJsWrappedPythonFunctionThrowsPyException(self):
-        thecx = []
-        def hai2u(cx, this, args):
-            thecx.append(cx)
-            raise Exception("hello")
-        self.assertRaises(pymonkey.error,
-                          self._evalJsWrappedPyFunc,
-                          hai2u, 'hai2u()')
-        exc = thecx[0].get_object_private(self.last_exception.args[0])
-        self.assertEqual(exc.args[0], "hello")
-
-    def testJsWrappedPythonFunctionReturnsNone(self):
-        def hai2u(cx, this, args):
-            pass
-        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
-                         None)
-
-    def testJsWrappedPythonFunctionReturnsTrue(self):
-        def hai2u(cx, this, args):
-            return True
-        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
-                         True)
-
-    def testJsWrappedPythonFunctionReturnsFalse(self):
-        def hai2u(cx, this, args):
-            return False
-        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
-                         False)
-
-    def testJsWrappedPythonFunctionReturnsSmallInt(self):
-        def hai2u(cx, this, args):
-            return 5
-        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
-                         5)
-
-    def testJsWrappedPythonFunctionReturnsFloat(self):
-        def hai2u(cx, this, args):
-            return 5.1
-        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
-                         5.1)
-
-    def testJsWrappedPythonFunctionReturnsNegativeInt(self):
-        def hai2u(cx, this, args):
-            return -5
-        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
-                         -5)
-
-    def testJsWrappedPythonFunctionReturnsBigInt(self):
-        def hai2u(cx, this, args):
-            return 2147483647
-        self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
-                         2147483647)
-
-    def testHasPropertyWorks(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        foo = cx.new_object()
-        cx.define_property(obj, u"foo\u2026", foo)
-        self.assertTrue(cx.has_property(obj, u"foo\u2026"))
-        self.assertFalse(cx.has_property(obj, "bar"))
-
-    def testDefinePropertyWorksWithUnicodePropertyNames(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        foo = cx.new_object()
-        cx.define_property(obj, u"foo\u2026", foo)
-        self.assertEqual(
-            cx.get_property(obj, u"foo\u2026"),
-            foo
-            )
-
-    def testDefinePropertyWorksWithObject(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        foo = cx.new_object()
-        cx.define_property(obj, "foo", foo)
-        self.assertEqual(
-            cx.evaluate_script(obj, 'foo', '<string>', 1),
-            foo
-            )
-
-    def testDefinePropertyWorksWithString(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        foo = cx.new_object()
-        cx.define_property(obj, "foo", u"hello")
-        self.assertEqual(
-            cx.evaluate_script(obj, 'foo', '<string>', 1),
-            u"hello"
-            )
-
-    def testObjectIsIdentityPreserving(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        cx.evaluate_script(obj, 'var foo = {bar: 1}', '<string>', 1)
-        self.assertTrue(isinstance(cx.get_property(obj, u"foo"),
-                                   pymonkey.Object))
-        self.assertTrue(cx.get_property(obj, u"foo") is
-                        cx.get_property(obj, "foo"))
-
-    def testObjectGetattrThrowsException(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        result = cx.evaluate_script(obj, '({get foo() { throw "blah"; }})',
-                                    '<string>', 1)
-        self.assertRaises(pymonkey.error,
-                          cx.get_property,
-                          result,
-                          u"foo")
-        self.assertEqual(self.last_exception.args[0], u"blah")
-
-    def testInfiniteRecursionRaisesError(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        self.assertRaises(
-            pymonkey.error,
-            cx.evaluate_script,
-            obj, '(function foo() { foo(); })();', '<string>', 1
-            )
-        self.assertEqual(
-            self._tostring(cx, self.last_exception.args[0]),
-            "InternalError: too much recursion"
-            )
-
-    def testObjectGetattrWorks(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        cx.evaluate_script(obj, 'var boop = 5', '<string>', 1)
-        cx.evaluate_script(obj, 'this["blarg\u2026"] = 5', '<string>', 1)
-        self.assertEqual(cx.get_property(obj, u"beans"),
-                         pymonkey.undefined)
-        self.assertEqual(cx.get_property(obj, u"blarg\u2026"), 5)
-        self.assertEqual(cx.get_property(obj, u"boop"), 5)
-
-    def testContextIsInstance(self):
-        cx = pymonkey.Runtime().new_context()
-        self.assertTrue(isinstance(cx, pymonkey.Context))
-
-    def testContextTypeCannotBeInstantiated(self):
-        self.assertRaises(TypeError, pymonkey.Context)
-
-    def testObjectIsInstance(self):
-        obj = pymonkey.Runtime().new_context().new_object()
-        self.assertTrue(isinstance(obj, pymonkey.Object))
-        self.assertFalse(isinstance(obj, pymonkey.Function))
-
-    def testObjectTypeCannotBeInstantiated(self):
-        self.assertRaises(TypeError, pymonkey.Object)
-
-    def testFunctionIsInstance(self):
-        def boop():
-            pass
-        obj = pymonkey.Runtime().new_context().new_function(boop, "boop")
-        self.assertTrue(isinstance(obj, pymonkey.Object))
-        self.assertTrue(isinstance(obj, pymonkey.Function))
-
-    def testFunctionTypeCannotBeInstantiated(self):
-        self.assertRaises(TypeError, pymonkey.Function)
-
-    def testObjectGetRuntimeWorks(self):
-        rt = pymonkey.Runtime()
-        obj = rt.new_context().new_object()
-        self.assertEqual(obj.get_runtime(), rt)
-
-    def testContextGetRuntimeWorks(self):
-        rt = pymonkey.Runtime()
-        cx = rt.new_context()
-        self.assertEqual(cx.get_runtime(), rt)
-
-    def testRuntimesAreWeakReferencable(self):
-        rt = pymonkey.Runtime()
-        wrt = weakref.ref(rt)
-        self.assertEqual(rt, wrt())
-        del rt
-        self.assertEqual(wrt(), None)
-
-    def testContextsAreWeakReferencable(self):
-        rt = pymonkey.Runtime()
-        cx = rt.new_context()
-        wcx = weakref.ref(cx)
-        self.assertEqual(cx, wcx())
-        del cx
-        self.assertEqual(wcx(), None)
-
-    def testUndefinedCannotBeInstantiated(self):
-        self.assertRaises(TypeError, pymonkey.undefined)
-
-    def testEvaluateThrowsException(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        self.assertRaises(pymonkey.error,
-                          cx.evaluate_script,
-                          obj, 'hai2u()', '<string>', 1)
-        self.assertEqual(self._tostring(cx,
-                                        self.last_exception.args[0]),
-                         'ReferenceError: hai2u is not defined')
-
-    def testThrowingObjWithBadToStringWorks(self):
-        self.assertRaises(
-            pymonkey.error,
-            self._evaljs,
-            "throw {toString: function() { throw 'dujg' }}"
-            )
-        self.assertEqual(
-            self.last_exception.args[1],
-            "<string conversion failed>"
-            )
-
-    def testEvaluateTakesUnicodeCode(self):
-        self.assertEqual(self._evaljs(u"'foo\u2026'"),
-                         u"foo\u2026")
-
-    def testEvaluateReturnsUndefined(self):
-        retval = self._evaljs("")
-        self.assertTrue(retval is pymonkey.undefined)
-
-    def testEvaludateReturnsUnicodeWithEmbeddedNULs(self):
-        retval = self._evaljs("'\x00hi'")
-        self.assertEqual(retval, u'\x00hi')
-
-    def testEvaluateReturnsSMPUnicode(self):
-        # This is 'LINEAR B SYLLABLE B008 A', in the supplementary
-        # multilingual plane (SMP).
-        retval = self._evaljs("'\uD800\uDC00'")
-        self.assertEqual(retval, u'\U00010000')
-        self.assertEqual(retval.encode('utf-16'),
-                         '\xff\xfe\x00\xd8\x00\xdc')
-
-    def testEvaluateReturnsBMPUnicode(self):
-        retval = self._evaljs("'o hai\u2026'")
-        self.assertTrue(type(retval) == unicode)
-        self.assertEqual(retval, u'o hai\u2026')
-
-    def testEvaluateReturnsObject(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        obj = cx.evaluate_script(obj, '({boop: 1})', '<string>', 1)
-        self.assertTrue(isinstance(obj, pymonkey.Object))
-        self.assertEqual(cx.get_property(obj, u"boop"), 1)
-
-    def testScriptedFunctionsHaveFilenameInfo(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        jsfunc = cx.evaluate_script(obj,
-                                    '(function boop() { \nreturn 1; })',
-                                    'somefile', 5)
-        self.assertEqual(jsfunc.filename, 'somefile')
-        self.assertEqual(jsfunc.base_lineno, 5)
-        self.assertEqual(jsfunc.line_extent, 2)
-
-    def testEvaluateReturnsFunction(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        cx.init_standard_classes(obj)
-        obj = cx.evaluate_script(obj, '(function boop() { return 1; })',
-                                 '<string>', 1)
-        self.assertTrue(isinstance(obj, pymonkey.Function))
-
-    def testJsExceptionStateIsClearedAfterExceptionIsCaught(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        self.assertRaises(pymonkey.error,
-                          cx.evaluate_script,
-                          obj, 'blah()', '<string>', 1)
-        self.assertEqual(cx.evaluate_script(obj, '5+3', '<string>', 1),
-                         8)
-
-    def testCallFunctionRaisesErrorOnBadFuncArgs(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        obj = cx.evaluate_script(
-            obj,
-            '(function boop(a, b) { return a+b+this.c; })',
-            '<string>', 1
-            )
-        self.assertRaises(
-            NotImplementedError,
-            cx.call_function,
-            obj, obj, (1, self)
-            )
-
-    def _tostring(self, cx, obj):
-        return cx.call_function(obj,
-                                cx.get_property(obj, u"toString"),
-                                ())
-
-    def testCallFunctionRaisesErrorFromJS(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        obj = cx.evaluate_script(
-            obj,
-            '(function boop(a, b) { blarg(); })',
-            '<string>', 1
-            )
-        self.assertRaises(pymonkey.error,
-                          cx.call_function,
-                          obj, obj, (1,))
-        self.assertEqual(self._tostring(cx,
-                                        self.last_exception.args[0]),
-                         'ReferenceError: blarg is not defined')
-
-    def testInitStandardClassesRaisesExcOnRuntimeMismatch(self):
-        cx2 = pymonkey.Runtime().new_context()
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        self.assertRaises(ValueError,
-                          cx2.init_standard_classes,
-                          obj)
-        self.assertEqual(self.last_exception.args[0],
-                         'JS runtime mismatch')
-
-    def testCallFunctionWorks(self):
-        cx = pymonkey.Runtime().new_context()
-        obj = cx.new_object()
-        thisArg = cx.new_object()
-        cx.define_property(thisArg, "c", 3)
-        cx.init_standard_classes(obj)
-        obj = cx.evaluate_script(
-            obj,
-            '(function boop(a, b) { return a+b+this.c; })',
-            '<string>', 1
-            )
-        self.assertEqual(cx.call_function(thisArg, obj, (1,2)), 6)
-
-    def testEvaluateReturnsTrue(self):
-        self.assertTrue(self._evaljs('true') is True)
-
-    def testEvaluateReturnsFalse(self):
-        self.assertTrue(self._evaljs('false') is False)
-
-    def testEvaluateReturnsNone(self):
-        self.assertTrue(self._evaljs('null') is None)
-
-    def testEvaluateReturnsIntegers(self):
-        self.assertEqual(self._evaljs('1+3'), 4)
-
-    def testEvaluateReturnsNegativeIntegers(self):
-        self.assertEqual(self._evaljs('-5'), -5)
-
-    def testEvaluateReturnsBigIntegers(self):
-        self.assertEqual(self._evaljs('2147483647*2'),
-                         2147483647*2)
-
-    def testEvaluateReturnsFloats(self):
-        self.assertEqual(self._evaljs('1.1+3'), 4.1)
-
-if __name__ == '__main__':
-    unittest.main()