annotate pydershell/pydershell.py @ 17:1d62177c5c27

Added a safe js object wrapper.
author Atul Varma <varmaa@toolness.com>
date Mon, 07 Sep 2009 04:23:09 -0700
parents a78570a423ea
children 69e5523ebdc6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
1 #! /usr/bin/env python
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
2
10
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
3 import sys
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
4 import time
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
5 import threading
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
6 import traceback
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
7 import weakref
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
8
10
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
9 import pydermonkey
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
10
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
11 class ContextWatchdogThread(threading.Thread):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
12 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
13 Watches active JS contexts and triggers their operation callbacks
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
14 at a regular interval.
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
15 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
16
13
2a3313bfe574 Minor refactoring.
Atul Varma <varmaa@toolness.com>
parents: 12
diff changeset
17 DEFAULT_INTERVAL = 0.25
2a3313bfe574 Minor refactoring.
Atul Varma <varmaa@toolness.com>
parents: 12
diff changeset
18
2a3313bfe574 Minor refactoring.
Atul Varma <varmaa@toolness.com>
parents: 12
diff changeset
19 def __init__(self, interval=DEFAULT_INTERVAL):
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
20 threading.Thread.__init__(self)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
21 self._lock = threading.Lock()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
22 self._stop = threading.Event()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
23 self._contexts = []
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
24 self.interval = interval
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
25 self.setDaemon(True)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
26
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
27 def add_context(self, cx):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
28 self._lock.acquire()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
29 try:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
30 self._contexts.append(weakref.ref(cx))
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
31 finally:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
32 self._lock.release()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
33
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
34 def join(self):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
35 self._stop.set()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
36 threading.Thread.join(self)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
37
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
38 def run(self):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
39 while not self._stop.isSet():
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
40 time.sleep(self.interval)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
41 new_list = []
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
42 self._lock.acquire()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
43 try:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
44 for weakcx in self._contexts:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
45 cx = weakcx()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
46 if cx:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
47 new_list.append(weakcx)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
48 cx.trigger_operation_callback()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
49 self._contexts = new_list
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
50 finally:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
51 self._lock.release()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
52
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
53 # Create a global watchdog.
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
54 watchdog = ContextWatchdogThread()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
55 watchdog.start()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
56
11
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
57 class InternalError(BaseException):
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
58 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
59 Represents an error in a JS-wrapped Python function that wasn't
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
60 expected to happen; because it's derived from BaseException, it
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
61 unrolls the whole JS/Python stack so that the error can be
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
62 reported to the outermost calling code.
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
63 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
64
11
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
65 def __init__(self):
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
66 BaseException.__init__(self)
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
67 self.exc_info = sys.exc_info()
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
68
17
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
69 class SafeJsObjectWrapper(object):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
70 """
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
71 Securely wraps a JS object to behave like any normal Python object.
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
72 """
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
73
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
74 __slots__ = ['_jsobject', '_cx', '_this']
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
75
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
76 def __init__(self, cx, jsobject, this):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
77 if not isinstance(jsobject, pydermonkey.Object):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
78 raise TypeError("Cannot wrap '%s' object" %
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
79 type(jsobject).__name__)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
80 object.__setattr__(self, '_jsobject', jsobject)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
81 object.__setattr__(self, '_cx', cx)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
82 object.__setattr__(self, '_this', this)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
83
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
84 def __wrap_to_python(self, value):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
85 if isinstance(value, pydermonkey.Object):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
86 return SafeJsObjectWrapper(self._cx, value, self._jsobject)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
87 else:
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
88 return value
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
89
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
90 def __wrap_to_js(self, value):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
91 # TODO: Add support for wrapping non-primitive python objects.
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
92 return value
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
93
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
94 def __call__(self, *args):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
95 cx = self._cx
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
96 jsobject = self._jsobject
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
97 this = self._this
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
98
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
99 if isinstance(jsobject, pydermonkey.Function):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
100 obj = cx.call_function(this, jsobject,
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
101 self.__wrap_to_js(args))
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
102 return self.__wrap_to_python(obj)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
103 else:
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
104 raise TypeError("'%s' object is not callable" %
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
105 type(jsobject).__name__)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
106
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
107 def __eq__(self, other):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
108 if isinstance(other, SafeJsObjectWrapper):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
109 return self._jsobject == other._jsobject
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
110 else:
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
111 return False
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
112
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
113 def __str__(self):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
114 return self.toString()
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
115
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
116 def __unicode__(self):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
117 return self.toString()
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
118
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
119 def __setitem__(self, item, value):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
120 self.__setattr__(item, value)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
121
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
122 def __setattr__(self, name, value):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
123 cx = self._cx
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
124 jsobject = self._jsobject
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
125
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
126 cx.define_property(jsobject, name,
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
127 self.__wrap_to_js(value))
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
128
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
129 def __getitem__(self, item):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
130 return self.__getattr__(item)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
131
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
132 def __getattr__(self, name):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
133 cx = self._cx
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
134 jsobject = self._jsobject
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
135
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
136 return self.__wrap_to_python(cx.get_property(jsobject, name))
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
137
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
138 def __contains__(self, item):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
139 cx = self._cx
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
140 jsobject = self._jsobject
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
141
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
142 return cx.has_property(jsobject, item)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
143
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
144 def __iter__(self):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
145 cx = self._cx
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
146 jsobject = self._jsobject
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
147
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
148 properties = cx.enumerate(jsobject)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
149 for property in properties:
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
150 yield property
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
151
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
152 def safejsfunc(cx, on_obj, name=None):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
153 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
154 Exposes the decorated Python function on the given JS object.
10
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
155
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
156 Any unexpected exceptions raised by the function will be
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
157 re-raised as InternalError exceptions.
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
158 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
159
11
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
160 def make_wrapper(func):
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
161 if name is None:
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
162 func_name = func.__name__
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
163 else:
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
164 func_name = name
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
165 def wrapper(func_cx, this, args):
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
166 try:
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
167 return func(func_cx, this, args)
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
168 except pydermonkey.error:
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
169 raise
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
170 except Exception:
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
171 raise InternalError()
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
172 cx.define_property(
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
173 on_obj,
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
174 func_name,
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
175 cx.new_function(wrapper, func_name)
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
176 )
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
177 return func
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
178 return make_wrapper
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
179
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
180 def format_stack(js_stack):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
181 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
182 Returns a formatted Python-esque stack traceback of the given
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
183 JS stack.
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
184 """
10
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
185
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
186 STACK_LINE =" File \"%(filename)s\", line %(lineno)d, in %(name)s"
10
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
187
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
188 lines = []
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
189 while js_stack:
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
190 script = js_stack['script']
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
191 function = js_stack['function']
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
192 if script:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
193 frameinfo = dict(filename = script.filename,
16
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
194 lineno = js_stack['lineno'],
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
195 name = '<module>')
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
196 elif function and not function.is_python:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
197 frameinfo = dict(filename = function.filename,
16
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
198 lineno = js_stack['lineno'],
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
199 name = function.name)
10
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
200 else:
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
201 frameinfo = None
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
202 if frameinfo:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
203 lines.insert(0, STACK_LINE % frameinfo)
16
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
204 try:
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
205 filelines = open(frameinfo['filename']).readlines()
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
206 line = filelines[frameinfo['lineno'] - 1].strip()
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
207 lines.insert(1, " %s" % line)
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
208 except Exception:
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
209 pass
10
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
210 js_stack = js_stack['caller']
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
211 lines.insert(0, "Traceback (most recent call last):")
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
212 return '\n'.join(lines)
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
213
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
214 class JSRuntime(object):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
215 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
216 A JS runtime capable of loading and executing scripts.
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
217 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
218
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
219 def __init__(self, watchdog=watchdog):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
220 rt = pydermonkey.Runtime()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
221 cx = rt.new_context()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
222 globalobj = cx.new_object()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
223 cx.init_standard_classes(globalobj)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
224
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
225 @safejsfunc(cx, globalobj)
17
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
226 def bar(cx, this, args):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
227 obj = SafeJsObjectWrapper(cx, args[0], this)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
228 print obj.bar()
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
229
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
230 @safejsfunc(cx, globalobj)
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
231 def foo(cx, this, args):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
232 return cx.call_function(this, args[0], ())
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
233
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
234 @safejsfunc(cx, globalobj, 'print')
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
235 def jsprint(cx, this, args):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
236 if len(args) > 0:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
237 print args[0]
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
238
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
239 cx.set_operation_callback(self._opcb)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
240 cx.set_throw_hook(self._throwhook)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
241 watchdog.add_context(cx)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
242
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
243 self.rt = rt
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
244 self.cx = cx
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
245 self.globalobj = globalobj
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
246 self.curr_exc = None
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
247 self.py_stack = None
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
248 self.js_stack = None
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
249
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
250 def _opcb(self, cx):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
251 # Don't do anything; if a keyboard interrupt was triggered,
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
252 # it'll get raised here automatically.
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
253 pass
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
254
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
255 def _throwhook(self, cx):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
256 curr_exc = cx.get_pending_exception()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
257 if self.curr_exc != curr_exc:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
258 self.curr_exc = curr_exc
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
259 self.py_stack = traceback.extract_stack()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
260 self.js_stack = cx.get_stack()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
261
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
262 def run_script(self, filename):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
263 contents = open(filename).read()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
264 cx = self.cx
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
265 try:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
266 cx.evaluate_script(self.globalobj, contents,
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
267 filename, 1)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
268 except pydermonkey.error, e:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
269 print format_stack(self.js_stack)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
270 print e.args[1]
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
271 except InternalError, e:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
272 print "An internal error occurred."
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
273 traceback.print_tb(e.exc_info[2])
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
274 print e.exc_info[1]
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
275
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
276 if __name__ == '__main__':
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
277 runtime = JSRuntime()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
278 runtime.run_script('test.js')
14
9bcbf780581f Added a del statement that makes pydermonkey crash.
Atul Varma <varmaa@toolness.com>
parents: 13
diff changeset
279 del runtime
15
351525e95a45 Added memory leak detection.
Atul Varma <varmaa@toolness.com>
parents: 14
diff changeset
280
351525e95a45 Added memory leak detection.
Atul Varma <varmaa@toolness.com>
parents: 14
diff changeset
281 import gc
351525e95a45 Added memory leak detection.
Atul Varma <varmaa@toolness.com>
parents: 14
diff changeset
282 gc.collect()
351525e95a45 Added memory leak detection.
Atul Varma <varmaa@toolness.com>
parents: 14
diff changeset
283 if pydermonkey.get_debug_info()['runtime_count']:
351525e95a45 Added memory leak detection.
Atul Varma <varmaa@toolness.com>
parents: 14
diff changeset
284 print "WARNING: JS runtime was not destroyed."