view docs/src/pymonkey.txt @ 115:f4c550369332

Added documentation for gc() and operation callback functions.
author Atul Varma <varmaa@toolness.com>
date Mon, 17 Aug 2009 03:33:40 -0700
parents 87147faa031a
children 06269ca0b36c
line wrap: on
line source

: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.

.. 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

   .. 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`.

.. 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

   .. method:: get_runtime()

      Returns the :class:`Runtime` that the context belongs to.

   .. 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:: 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:: 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:: 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:

        >>> 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)
        >>> def watchdog_thread():
        ...   time.sleep(0.1)
        ...   cx.trigger_operation_callback()
        >>> thread = threading.Thread(target=watchdog_thread)
        >>> thread.start()
        >>> 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.

   .. 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.