annotate pydershell/pydershell.py @ 22:9413bebf2ee6

Separated the test functionality out into a separate file.
author Atul Varma <varmaa@toolness.com>
date Mon, 07 Sep 2009 16:18:34 -0700
parents 1950b0b5bcd8
children 35ab0ad3c294
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
1 import sys
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
2 import time
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
3 import threading
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
4 import traceback
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
5 import weakref
21
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
6 import types
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
7
10
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
8 import pydermonkey
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
9
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
10 class ContextWatchdogThread(threading.Thread):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
11 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
12 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
13 at a regular interval.
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
14 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
15
13
2a3313bfe574 Minor refactoring.
Atul Varma <varmaa@toolness.com>
parents: 12
diff changeset
16 DEFAULT_INTERVAL = 0.25
2a3313bfe574 Minor refactoring.
Atul Varma <varmaa@toolness.com>
parents: 12
diff changeset
17
2a3313bfe574 Minor refactoring.
Atul Varma <varmaa@toolness.com>
parents: 12
diff changeset
18 def __init__(self, interval=DEFAULT_INTERVAL):
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
19 threading.Thread.__init__(self)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
20 self._lock = threading.Lock()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
21 self._stop = threading.Event()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
22 self._contexts = []
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
23 self.interval = interval
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
24 self.setDaemon(True)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
25
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
26 def add_context(self, cx):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
27 self._lock.acquire()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
28 try:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
29 self._contexts.append(weakref.ref(cx))
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
30 finally:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
31 self._lock.release()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
32
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
33 def join(self):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
34 self._stop.set()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
35 threading.Thread.join(self)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
36
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
37 def run(self):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
38 while not self._stop.isSet():
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
39 time.sleep(self.interval)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
40 new_list = []
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
41 self._lock.acquire()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
42 try:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
43 for weakcx in self._contexts:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
44 cx = weakcx()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
45 if cx:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
46 new_list.append(weakcx)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
47 cx.trigger_operation_callback()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
48 self._contexts = new_list
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
49 finally:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
50 self._lock.release()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
51
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
52 # Create a global watchdog.
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
53 watchdog = ContextWatchdogThread()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
54 watchdog.start()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
55
11
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
56 class InternalError(BaseException):
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
57 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
58 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
59 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
60 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
61 reported to the outermost calling code.
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
62 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
63
11
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
64 def __init__(self):
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
65 BaseException.__init__(self)
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
66 self.exc_info = sys.exc_info()
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
67
17
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
68 class SafeJsObjectWrapper(object):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
69 """
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
70 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
71 """
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
72
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
73 __slots__ = ['_jsobject', '_sandbox', '_this']
17
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
74
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
75 def __init__(self, sandbox, jsobject, this):
17
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
76 if not isinstance(jsobject, pydermonkey.Object):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
77 raise TypeError("Cannot wrap '%s' object" %
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
78 type(jsobject).__name__)
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
79 object.__setattr__(self, '_sandbox', sandbox)
17
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, '_this', this)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
82
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
83 @property
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
84 def wrapped_jsobject(self):
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
85 return self._jsobject
17
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
86
18
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
87 def _wrap_to_python(self, jsvalue):
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
88 return self._sandbox.wrap_jsobject(jsvalue, self._jsobject)
18
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
89
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
90 def _wrap_to_js(self, value):
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
91 return self._sandbox.wrap_pyobject(value)
17
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
92
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
93 def __eq__(self, other):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
94 if isinstance(other, SafeJsObjectWrapper):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
95 return self._jsobject == other._jsobject
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
96 else:
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
97 return False
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 def __str__(self):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
100 return self.toString()
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
101
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
102 def __unicode__(self):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
103 return self.toString()
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
104
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
105 def __setitem__(self, item, value):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
106 self.__setattr__(item, value)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
107
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
108 def __setattr__(self, name, value):
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
109 cx = self._sandbox.cx
17
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
110 jsobject = self._jsobject
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
111
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
112 cx.define_property(jsobject, name,
18
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
113 self._wrap_to_js(value))
17
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
114
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
115 def __getitem__(self, item):
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
116 return self.__getattr__(item)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
117
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
118 def __getattr__(self, name):
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
119 cx = self._sandbox.cx
17
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
120 jsobject = self._jsobject
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
121
18
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
122 return self._wrap_to_python(cx.get_property(jsobject, name))
17
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
123
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
124 def __contains__(self, item):
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
125 cx = self._sandbox.cx
17
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
126 jsobject = self._jsobject
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
127
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
128 return cx.has_property(jsobject, item)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
129
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
130 def __iter__(self):
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
131 cx = self._sandbox.cx
17
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
132 jsobject = self._jsobject
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
133
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
134 properties = cx.enumerate(jsobject)
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
135 for property in properties:
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
136 yield property
1d62177c5c27 Added a safe js object wrapper.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
137
18
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
138 class SafeJsFunctionWrapper(SafeJsObjectWrapper):
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
139 """
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
140 Securely wraps a JS function to behave like any normal Python object.
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
141 """
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
142
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
143 def __init__(self, sandbox, jsfunction, this):
18
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
144 if not isinstance(jsfunction, pydermonkey.Function):
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
145 raise TypeError("Cannot wrap '%s' object" %
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
146 type(jsobject).__name__)
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
147 SafeJsObjectWrapper.__init__(self, sandbox, jsfunction, this)
18
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
148
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
149 def __call__(self, *args):
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
150 cx = self._sandbox.cx
18
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
151 jsobject = self._jsobject
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
152 this = self._this
69e5523ebdc6 Separated out SafeJsObjectWrapper into itself and a new subclass, SafeJsFunctionWrapper, so that callable() works properly on instances.
Atul Varma <varmaa@toolness.com>
parents: 17
diff changeset
153
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
154 arglist = []
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
155 for arg in args:
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
156 arglist.append(self._wrap_to_js(arg))
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
157
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
158 obj = cx.call_function(this, jsobject, tuple(arglist))
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
159 return self._wrap_to_python(obj)
11
74f27983a350 Added more to pydershell.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
160
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
161 def format_stack(js_stack):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
162 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
163 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
164 JS stack.
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
165 """
10
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
166
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
167 STACK_LINE =" File \"%(filename)s\", line %(lineno)d, in %(name)s"
10
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
168
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
169 lines = []
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
170 while js_stack:
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
171 script = js_stack['script']
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
172 function = js_stack['function']
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
173 if script:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
174 frameinfo = dict(filename = script.filename,
16
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
175 lineno = js_stack['lineno'],
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
176 name = '<module>')
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
177 elif function and not function.is_python:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
178 frameinfo = dict(filename = function.filename,
16
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
179 lineno = js_stack['lineno'],
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
180 name = function.name)
10
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
181 else:
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
182 frameinfo = None
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
183 if frameinfo:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
184 lines.insert(0, STACK_LINE % frameinfo)
16
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
185 try:
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
186 filelines = open(frameinfo['filename']).readlines()
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
187 line = filelines[frameinfo['lineno'] - 1].strip()
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
188 lines.insert(1, " %s" % line)
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
189 except Exception:
a78570a423ea Show code excerpts in js stack tracebacks
Atul Varma <varmaa@toolness.com>
parents: 15
diff changeset
190 pass
10
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
191 js_stack = js_stack['caller']
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
192 lines.insert(0, "Traceback (most recent call last):")
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
193 return '\n'.join(lines)
fb25af17bae6 Added pydershell.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
194
21
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
195 class JsExposedObject(object):
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
196 """
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
197 Trivial base/mixin class for any Python classes that choose to
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
198 expose themselves to JS code.
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
199 """
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
200
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
201 pass
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
202
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
203 class JsSandbox(object):
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
204 """
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
205 A JS runtime and associated functionality capable of securely
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
206 loading and executing scripts.
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
207 """
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
208
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
209 def __init__(self, watchdog=watchdog):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
210 rt = pydermonkey.Runtime()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
211 cx = rt.new_context()
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
212 root = cx.new_object()
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
213 cx.init_standard_classes(root)
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
214
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
215 cx.set_operation_callback(self._opcb)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
216 cx.set_throw_hook(self._throwhook)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
217 watchdog.add_context(cx)
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 self.rt = rt
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
220 self.cx = cx
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
221 self.curr_exc = None
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
222 self.py_stack = None
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
223 self.js_stack = None
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
224 self.__py_to_js = {}
21
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
225 self.__type_protos = {}
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
226 self.root = self.wrap_jsobject(root, root)
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
227
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
228 def finish(self):
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
229 for jsobj in self.__py_to_js.values():
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
230 self.cx.clear_object_private(jsobj)
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
231 del self.__py_to_js
21
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
232 del self.__type_protos
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
233 del self.curr_exc
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
234 del self.py_stack
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
235 del self.js_stack
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
236 del self.cx
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
237 del self.rt
12
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 def _opcb(self, cx):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
240 # 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
241 # it'll get raised here automatically.
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
242 pass
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
243
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
244 def _throwhook(self, cx):
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
245 curr_exc = cx.get_pending_exception()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
246 if self.curr_exc != curr_exc:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
247 self.curr_exc = curr_exc
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
248 self.py_stack = traceback.extract_stack()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
249 self.js_stack = cx.get_stack()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
250
21
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
251 def __wrap_pycallable(self, func, pyproto=None):
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
252 if func in self.__py_to_js:
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
253 return self.__py_to_js[func]
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
254
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
255 if hasattr(func, '__name__'):
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
256 name = func.__name__
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
257 else:
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
258 name = ""
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
259
21
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
260 if pyproto:
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
261 def wrapper(func_cx, this, args):
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
262 try:
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
263 arglist = []
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
264 for arg in args:
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
265 arglist.append(self.wrap_jsobject(arg))
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
266 instance = func_cx.get_object_private(this)
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
267 if instance is None or not isinstance(instance, pyproto):
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
268 raise pydermonkey.error("Method type mismatch")
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
269
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
270 # TODO: Fill in extra required params with
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
271 # pymonkey.undefined? or automatically throw an
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
272 # exception to calling js code?
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
273 return self.wrap_pyobject(func(instance, *arglist))
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
274 except pydermonkey.error:
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
275 raise
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
276 except Exception:
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
277 raise InternalError()
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
278 else:
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
279 def wrapper(func_cx, this, args):
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
280 try:
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
281 arglist = []
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
282 for arg in args:
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
283 arglist.append(self.wrap_jsobject(arg))
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
284
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
285 # TODO: Fill in extra required params with
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
286 # pymonkey.undefined? or automatically throw an
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
287 # exception to calling js code?
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
288 return self.wrap_pyobject(func(*arglist))
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
289 except pydermonkey.error:
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
290 raise
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
291 except Exception:
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
292 raise InternalError()
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
293 wrapper.wrapped_pyobject = func
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
294 wrapper.__name__ = name
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
295
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
296 jsfunc = self.cx.new_function(wrapper, name)
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
297 self.__py_to_js[func] = jsfunc
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
298
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
299 return jsfunc
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
300
21
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
301 def __wrap_pyinstance(self, value):
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
302 pyproto = type(value)
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
303 if pyproto not in self.__type_protos:
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
304 jsproto = self.cx.new_object()
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
305 for name in dir(pyproto):
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
306 attr = getattr(pyproto, name)
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
307 if (isinstance(attr, types.UnboundMethodType) and
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
308 hasattr(attr, '__jsexposed__') and
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
309 attr.__jsexposed__):
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
310 jsmethod = self.__wrap_pycallable(attr, pyproto)
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
311 self.cx.define_property(jsproto, name, jsmethod)
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
312 self.__type_protos[pyproto] = jsproto
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
313 return self.cx.new_object(value, self.__type_protos[pyproto])
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
314
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
315 def wrap_pyobject(self, value):
21
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
316 if (isinstance(value, (int, basestring, float, bool)) or
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
317 value is pydermonkey.undefined or
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
318 value is None):
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
319 return value
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
320 if isinstance(value, SafeJsObjectWrapper):
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
321 # It's already wrapped, just unwrap it.
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
322 return value.wrapped_jsobject
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
323 elif callable(value):
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
324 return self.__wrap_pycallable(value)
21
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
325 elif isinstance(value, JsExposedObject):
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
326 return self.__wrap_pyinstance(value)
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
327 else:
21
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
328 raise TypeError("Can't expose objects of type '' to JS." %
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
329 type(value).__name__)
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
330
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
331 def wrap_jsobject(self, jsvalue, this=None):
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
332 if this is None:
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
333 this = self.root.wrapped_jsobject
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
334 if isinstance(jsvalue, pydermonkey.Function):
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
335 if jsvalue.is_python:
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
336 # It's a Python function, just unwrap it.
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
337 return self.cx.get_object_private(jsvalue).wrapped_pyobject
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
338 return SafeJsFunctionWrapper(self, jsvalue, this)
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
339 elif isinstance(jsvalue, pydermonkey.Object):
21
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
340 # It's a wrapped Python object instance, just unwrap it.
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
341 instance = self.cx.get_object_private(jsvalue)
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
342 if instance:
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
343 if not isinstance(instance, JsExposedObject):
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
344 raise AssertionError("Object private is not of type "
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
345 "JsExposedObject")
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
346 return instance
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
347 else:
1950b0b5bcd8 It's now possible to expose python class instances to JS, if they're declared the right way (for security purposes).
Atul Varma <varmaa@toolness.com>
parents: 20
diff changeset
348 return SafeJsObjectWrapper(self, jsvalue, this)
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
349 else:
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
350 # It's a primitive value.
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
351 return jsvalue
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
352
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
353 def run_script(self, filename):
20
8dd18f864351 pydershell now exits with a nonzero return code if the script it calls throws an exception.
Atul Varma <varmaa@toolness.com>
parents: 19
diff changeset
354 retval = -1
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
355 contents = open(filename).read()
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
356 cx = self.cx
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
357 try:
19
057260102960 Made wrapping of python objects much nicer.
Atul Varma <varmaa@toolness.com>
parents: 18
diff changeset
358 cx.evaluate_script(self.root.wrapped_jsobject, contents,
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
359 filename, 1)
20
8dd18f864351 pydershell now exits with a nonzero return code if the script it calls throws an exception.
Atul Varma <varmaa@toolness.com>
parents: 19
diff changeset
360 retval = 0
12
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
361 except pydermonkey.error, e:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
362 print format_stack(self.js_stack)
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
363 print e.args[1]
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
364 except InternalError, e:
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
365 print "An internal error occurred."
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
366 traceback.print_tb(e.exc_info[2])
f024e41d0fb9 More refactoring, a bit more documentation.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
367 print e.exc_info[1]
20
8dd18f864351 pydershell now exits with a nonzero return code if the script it calls throws an exception.
Atul Varma <varmaa@toolness.com>
parents: 19
diff changeset
368 return retval