annotate pydertron.py @ 10:97f3b2242505

Removed unused js files.
author Atul Varma <varmaa@toolness.com>
date Thu, 10 Sep 2009 11:09:14 -0700
parents a88d1cc4db92
children 665f69f61716
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
1 import os
0
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
2 import sys
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
3 import threading
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
4 import traceback
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
5 import weakref
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
6 import types
7
2117265e4dfe Fixed some threading issues.
Atul Varma <varmaa@toolness.com>
parents: 6
diff changeset
7 import atexit
0
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
8
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
9 import pydermonkey
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
10
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
11 class ContextWatchdogThread(threading.Thread):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
12 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
13 Watches active JS contexts and triggers their operation callbacks
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
14 at a regular interval.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
15 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
16
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
17 # Default interval, in seconds, that the operation callbacks are
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
18 # triggered at.
8
fb0b161542b1 Improved performance of watchdog thread.
Atul Varma <varmaa@toolness.com>
parents: 7
diff changeset
19 DEFAULT_INTERVAL = 0.25
0
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
20
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
21 def __init__(self, interval=DEFAULT_INTERVAL):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
22 threading.Thread.__init__(self)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
23 self._lock = threading.Lock()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
24 self._stop = threading.Event()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
25 self._contexts = []
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
26 self.interval = interval
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
27
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
28 def add_context(self, cx):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
29 self._lock.acquire()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
30 try:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
31 self._contexts.append(weakref.ref(cx))
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
32 finally:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
33 self._lock.release()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
34
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
35 def join(self):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
36 self._stop.set()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
37 threading.Thread.join(self)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
38
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
39 def run(self):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
40 while not self._stop.isSet():
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
41 new_list = []
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
42 self._lock.acquire()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
43 try:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
44 for weakcx in self._contexts:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
45 cx = weakcx()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
46 if cx:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
47 new_list.append(weakcx)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
48 cx.trigger_operation_callback()
7
2117265e4dfe Fixed some threading issues.
Atul Varma <varmaa@toolness.com>
parents: 6
diff changeset
49 del cx
0
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
50 self._contexts = new_list
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
51 finally:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
52 self._lock.release()
8
fb0b161542b1 Improved performance of watchdog thread.
Atul Varma <varmaa@toolness.com>
parents: 7
diff changeset
53 self._stop.wait(self.interval)
0
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
54
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
55 # Create a global watchdog.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
56 watchdog = ContextWatchdogThread()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
57 watchdog.start()
7
2117265e4dfe Fixed some threading issues.
Atul Varma <varmaa@toolness.com>
parents: 6
diff changeset
58 atexit.register(watchdog.join)
0
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
59
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
60 class InternalError(BaseException):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
61 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
62 Represents an error in a JS-wrapped Python function that wasn't
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
63 expected to happen; because it's derived from BaseException, it
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
64 unrolls the whole JS/Python stack so that the error can be
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
65 reported to the outermost calling code.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
66 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
67
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
68 def __init__(self):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
69 BaseException.__init__(self)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
70 self.exc_info = sys.exc_info()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
71
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
72 class SafeJsObjectWrapper(object):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
73 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
74 Securely wraps a JS object to behave like any normal Python object.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
75 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
76
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
77 __slots__ = ['_jsobject', '_sandbox', '_this']
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
78
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
79 def __init__(self, sandbox, jsobject, this):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
80 if not isinstance(jsobject, pydermonkey.Object):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
81 raise TypeError("Cannot wrap '%s' object" %
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
82 type(jsobject).__name__)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
83 object.__setattr__(self, '_sandbox', sandbox)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
84 object.__setattr__(self, '_jsobject', jsobject)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
85 object.__setattr__(self, '_this', this)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
86
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
87 @property
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
88 def wrapped_jsobject(self):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
89 return self._jsobject
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
90
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
91 def _wrap_to_python(self, jsvalue):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
92 return self._sandbox.wrap_jsobject(jsvalue, self._jsobject)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
93
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
94 def _wrap_to_js(self, value):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
95 return self._sandbox.wrap_pyobject(value)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
96
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
97 def __eq__(self, other):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
98 if isinstance(other, SafeJsObjectWrapper):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
99 return self._jsobject == other._jsobject
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
100 else:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
101 return False
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
102
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
103 def __str__(self):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
104 return self.toString()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
105
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
106 def __unicode__(self):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
107 return self.toString()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
108
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
109 def __setitem__(self, item, value):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
110 self.__setattr__(item, value)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
111
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
112 def __setattr__(self, name, value):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
113 cx = self._sandbox.cx
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
114 jsobject = self._jsobject
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
115
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
116 cx.define_property(jsobject, name,
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
117 self._wrap_to_js(value))
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
118
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
119 def __getitem__(self, item):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
120 return self.__getattr__(item)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
121
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
122 def __getattr__(self, name):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
123 cx = self._sandbox.cx
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
124 jsobject = self._jsobject
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
125
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
126 return self._wrap_to_python(cx.get_property(jsobject, name))
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
127
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
128 def __contains__(self, item):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
129 cx = self._sandbox.cx
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
130 jsobject = self._jsobject
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
131
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
132 return cx.has_property(jsobject, item)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
133
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
134 def __iter__(self):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
135 cx = self._sandbox.cx
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
136 jsobject = self._jsobject
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
137
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
138 properties = cx.enumerate(jsobject)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
139 for property in properties:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
140 yield property
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
141
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
142 class SafeJsFunctionWrapper(SafeJsObjectWrapper):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
143 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
144 Securely wraps a JS function to behave like any normal Python object.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
145 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
146
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
147 def __init__(self, sandbox, jsfunction, this):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
148 if not isinstance(jsfunction, pydermonkey.Function):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
149 raise TypeError("Cannot wrap '%s' object" %
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
150 type(jsobject).__name__)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
151 SafeJsObjectWrapper.__init__(self, sandbox, jsfunction, this)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
152
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
153 def __call__(self, *args):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
154 cx = self._sandbox.cx
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
155 jsobject = self._jsobject
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
156 this = self._this
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
157
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
158 arglist = []
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
159 for arg in args:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
160 arglist.append(self._wrap_to_js(arg))
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
161
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
162 obj = cx.call_function(this, jsobject, tuple(arglist))
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
163 return self._wrap_to_python(obj)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
164
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
165 def format_stack(js_stack):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
166 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
167 Returns a formatted Python-esque stack traceback of the given
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
168 JS stack.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
169 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
170
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
171 STACK_LINE =" File \"%(filename)s\", line %(lineno)d, in %(name)s"
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
172
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
173 lines = []
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
174 while js_stack:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
175 script = js_stack['script']
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
176 function = js_stack['function']
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
177 if script:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
178 frameinfo = dict(filename = script.filename,
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
179 lineno = js_stack['lineno'],
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
180 name = '<module>')
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
181 elif function and not function.is_python:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
182 frameinfo = dict(filename = function.filename,
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
183 lineno = js_stack['lineno'],
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
184 name = function.name)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
185 else:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
186 frameinfo = None
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
187 if frameinfo:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
188 lines.insert(0, STACK_LINE % frameinfo)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
189 try:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
190 filelines = open(frameinfo['filename']).readlines()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
191 line = filelines[frameinfo['lineno'] - 1].strip()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
192 lines.insert(1, " %s" % line)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
193 except Exception:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
194 pass
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
195 js_stack = js_stack['caller']
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
196 lines.insert(0, "Traceback (most recent call last):")
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
197 return '\n'.join(lines)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
198
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
199 def jsexposed(name=None, on=None):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
200 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
201 Decorator used to expose the decorated function or method to
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
202 untrusted JS.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
203
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
204 'name' is an optional alternative name for the function.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
205
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
206 'on' is an optional SafeJsObjectWrapper that the function can be
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
207 automatically attached as a property to.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
208 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
209
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
210 if callable(name):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
211 func = name
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
212 func.__jsexposed__ = True
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
213 return func
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
214
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
215 def make_exposed(func):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
216 if name:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
217 func.__name__ = name
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
218 func.__jsexposed__ = True
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
219 if on:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
220 on[func.__name__] = func
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
221 return func
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
222 return make_exposed
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
223
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
224 class JsExposedObject(object):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
225 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
226 Trivial base/mixin class for any Python classes that choose to
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
227 expose themselves to JS code.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
228 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
229
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
230 pass
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
231
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
232 class JsSandbox(object):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
233 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
234 A JS runtime and associated functionality capable of securely
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
235 loading and executing scripts.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
236 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
237
3
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
238 def __init__(self, watchdog=watchdog):
0
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
239 rt = pydermonkey.Runtime()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
240 cx = rt.new_context()
2
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
241 root_proto = cx.new_object()
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
242 cx.init_standard_classes(root_proto)
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
243 root = cx.new_object(None, root_proto)
0
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
244
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
245 cx.set_operation_callback(self._opcb)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
246 cx.set_throw_hook(self._throwhook)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
247 watchdog.add_context(cx)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
248
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
249 self.rt = rt
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
250 self.cx = cx
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
251 self.curr_exc = None
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
252 self.py_stack = None
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
253 self.js_stack = None
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
254 self.__py_to_js = {}
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
255 self.__type_protos = {}
2
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
256 self.root_proto = root_proto
0
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
257 self.root = self.wrap_jsobject(root, root)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
258
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
259 def finish(self):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
260 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
261 Cleans up all resources used by the sandbox, breaking any reference
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
262 cycles created due to issue #2 in pydermonkey:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
263
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
264 http://code.google.com/p/pydermonkey/issues/detail?id=2
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
265 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
266
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
267 for jsobj in self.__py_to_js.values():
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
268 self.cx.clear_object_private(jsobj)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
269 del self.__py_to_js
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
270 del self.__type_protos
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
271 del self.curr_exc
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
272 del self.py_stack
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
273 del self.js_stack
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
274 del self.cx
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
275 del self.rt
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
276
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
277 def _opcb(self, cx):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
278 # Don't do anything; if a keyboard interrupt was triggered,
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
279 # it'll get raised here automatically.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
280 pass
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
281
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
282 def _throwhook(self, cx):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
283 curr_exc = cx.get_pending_exception()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
284 if self.curr_exc != curr_exc:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
285 self.curr_exc = curr_exc
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
286 self.py_stack = traceback.extract_stack()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
287 self.js_stack = cx.get_stack()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
288
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
289 def __wrap_pycallable(self, func, pyproto=None):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
290 if func in self.__py_to_js:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
291 return self.__py_to_js[func]
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
292
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
293 if hasattr(func, '__name__'):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
294 name = func.__name__
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
295 else:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
296 name = ""
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
297
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
298 if pyproto:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
299 def wrapper(func_cx, this, args):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
300 try:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
301 arglist = []
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
302 for arg in args:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
303 arglist.append(self.wrap_jsobject(arg))
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
304 instance = func_cx.get_object_private(this)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
305 if instance is None or not isinstance(instance, pyproto):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
306 raise pydermonkey.error("Method type mismatch")
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
307
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
308 # TODO: Fill in extra required params with
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
309 # pymonkey.undefined? or automatically throw an
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
310 # exception to calling js code?
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
311 return self.wrap_pyobject(func(instance, *arglist))
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
312 except pydermonkey.error:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
313 raise
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
314 except Exception:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
315 raise InternalError()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
316 else:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
317 def wrapper(func_cx, this, args):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
318 try:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
319 arglist = []
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
320 for arg in args:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
321 arglist.append(self.wrap_jsobject(arg))
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
322
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
323 # TODO: Fill in extra required params with
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
324 # pymonkey.undefined? or automatically throw an
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
325 # exception to calling js code?
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
326 return self.wrap_pyobject(func(*arglist))
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
327 except pydermonkey.error:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
328 raise
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
329 except Exception:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
330 raise InternalError()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
331 wrapper.wrapped_pyobject = func
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
332 wrapper.__name__ = name
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
333
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
334 jsfunc = self.cx.new_function(wrapper, name)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
335 self.__py_to_js[func] = jsfunc
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
336
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
337 return jsfunc
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
338
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
339 def __wrap_pyinstance(self, value):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
340 pyproto = type(value)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
341 if pyproto not in self.__type_protos:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
342 jsproto = self.cx.new_object()
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
343 if hasattr(pyproto, '__jsprops__'):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
344 define_getter = self.cx.get_property(jsproto,
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
345 '__defineGetter__')
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
346 define_setter = self.cx.get_property(jsproto,
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
347 '__defineSetter__')
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
348 for name in pyproto.__jsprops__:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
349 prop = getattr(pyproto, name)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
350 if not type(prop) == property:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
351 raise TypeError("Expected attribute '%s' to "
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
352 "be a property" % name)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
353 getter = None
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
354 setter = None
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
355 if prop.fget:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
356 getter = self.__wrap_pycallable(prop.fget,
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
357 pyproto)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
358 if prop.fset:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
359 setter = self.__wrap_pycallable(prop.fset,
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
360 pyproto)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
361 if getter:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
362 self.cx.call_function(jsproto,
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
363 define_getter,
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
364 (name, getter))
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
365 if setter:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
366 self.cx.call_function(jsproto,
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
367 define_setter,
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
368 (name, setter,))
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
369 for name in dir(pyproto):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
370 attr = getattr(pyproto, name)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
371 if (isinstance(attr, types.UnboundMethodType) and
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
372 hasattr(attr, '__jsexposed__') and
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
373 attr.__jsexposed__):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
374 jsmethod = self.__wrap_pycallable(attr, pyproto)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
375 self.cx.define_property(jsproto, name, jsmethod)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
376 self.__type_protos[pyproto] = jsproto
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
377 return self.cx.new_object(value, self.__type_protos[pyproto])
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
378
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
379 def wrap_pyobject(self, value):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
380 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
381 Wraps the given Python object for export to untrusted JS.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
382
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
383 If the Python object isn't of a type that can be exposed to JS,
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
384 a TypeError is raised.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
385 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
386
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
387 if (isinstance(value, (int, basestring, float, bool)) or
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
388 value is pydermonkey.undefined or
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
389 value is None):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
390 return value
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
391 if isinstance(value, SafeJsObjectWrapper):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
392 # It's already wrapped, just unwrap it.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
393 return value.wrapped_jsobject
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
394 elif callable(value):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
395 if not (hasattr(value, '__jsexposed__') and
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
396 value.__jsexposed__):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
397 raise ValueError("Callable isn't configured for exposure "
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
398 "to untrusted JS code")
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
399 return self.__wrap_pycallable(value)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
400 elif isinstance(value, JsExposedObject):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
401 return self.__wrap_pyinstance(value)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
402 else:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
403 raise TypeError("Can't expose objects of type '%s' to JS." %
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
404 type(value).__name__)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
405
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
406 def wrap_jsobject(self, jsvalue, this=None):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
407 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
408 Wraps the given pydermonkey.Object for import to trusted
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
409 Python code. If the type is just a primitive, it's simply
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
410 returned, since no wrapping is needed.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
411 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
412
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
413 if this is None:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
414 this = self.root.wrapped_jsobject
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
415 if isinstance(jsvalue, pydermonkey.Function):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
416 if jsvalue.is_python:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
417 # It's a Python function, just unwrap it.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
418 return self.cx.get_object_private(jsvalue).wrapped_pyobject
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
419 return SafeJsFunctionWrapper(self, jsvalue, this)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
420 elif isinstance(jsvalue, pydermonkey.Object):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
421 # It's a wrapped Python object instance, just unwrap it.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
422 instance = self.cx.get_object_private(jsvalue)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
423 if instance:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
424 if not isinstance(instance, JsExposedObject):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
425 raise AssertionError("Object private is not of type "
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
426 "JsExposedObject")
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
427 return instance
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
428 else:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
429 return SafeJsObjectWrapper(self, jsvalue, this)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
430 else:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
431 # It's a primitive value.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
432 return jsvalue
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
433
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
434 def new_array(self, *contents):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
435 array = self.wrap_jsobject(self.cx.new_array_object())
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
436 for item in contents:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
437 array.push(item)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
438 return array
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
439
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
440 def new_object(self, **contents):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
441 obj = self.wrap_jsobject(self.cx.new_object())
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
442 for name in contents:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
443 obj[name] = contents[name]
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
444 return obj
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
445
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
446 def evaluate(self, code, filename='<string>', lineno=1):
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
447 retval = self.cx.evaluate_script(self.root.wrapped_jsobject,
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
448 code, filename, lineno)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
449 return self.wrap_jsobject(retval)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
450
6
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
451 def run_script(self, contents, filename='<string>', lineno=1,
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
452 callback=None):
0
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
453 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
454 Runs the given JS script, returning 0 on success, -1 on failure.
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
455 """
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
456
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
457 retval = -1
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
458 cx = self.cx
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
459 try:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
460 result = cx.evaluate_script(self.root.wrapped_jsobject,
6
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
461 contents, filename, lineno)
0
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
462 if callback:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
463 callback(self.wrap_jsobject(result))
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
464 retval = 0
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
465 except pydermonkey.error, e:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
466 print format_stack(self.js_stack)
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
467 print e.args[1]
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
468 except InternalError, e:
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
469 print "An internal error occurred."
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
470 traceback.print_tb(e.exc_info[2])
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
471 print e.exc_info[1]
a5b09b685df4 Origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
472 return retval
1
ab09b8a10876 Added trivial half-baked implementation of securable modules.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
473
3
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
474 class SecurableModuleLoader(object):
6
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
475 """
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
476 Loader for CommonJS SecurableModules.
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
477 """
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
478
3
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
479 def __init__(self, sandbox, root_dir, globals):
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
480 self.root_dir = root_dir
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
481 self.sandbox = sandbox
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
482 self.globals = globals
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
483 self.modules = {}
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
484 self._install_globals(sandbox.root)
2
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
485
3
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
486 def _install_globals(self, object):
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
487 for name in self.globals:
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
488 object[name] = self.globals[name]
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
489 object['require'] = self.require
1
ab09b8a10876 Added trivial half-baked implementation of securable modules.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
490
3
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
491 def _get_calling_script(self):
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
492 frame = self.sandbox.cx.get_stack()['caller']
2
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
493 curr_script = None
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
494 while frame and curr_script is None:
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
495 if frame['function'] and frame['function'].filename:
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
496 curr_script = frame['function'].filename
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
497 elif frame['script']:
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
498 curr_script = frame['script'].filename
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
499 frame = frame['caller']
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
500
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
501 if curr_script is None:
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
502 raise RuntimeError("Can't find calling script")
3
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
503 return curr_script
2
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
504
3
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
505 def _load_module(self, filename):
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
506 sandbox = self.sandbox
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
507 cx = sandbox.cx
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
508
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
509 module = cx.new_object(None, sandbox.root_proto)
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
510 cx.init_standard_classes(module)
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
511 exports = cx.new_object()
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
512 cx.define_property(module, 'exports', exports)
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
513 self._install_globals(sandbox.wrap_jsobject(module))
4
ae5869491e61 Added more to securablemodule impl.
Atul Varma <varmaa@toolness.com>
parents: 3
diff changeset
514 self.modules[filename] = sandbox.wrap_jsobject(exports)
3
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
515
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
516 contents = open(filename).read()
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
517 cx.evaluate_script(module, contents, filename, 1)
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
518
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
519 @jsexposed
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
520 def require(self, path):
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
521 curr_script = self._get_calling_script()
2
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
522 curr_dir = os.path.split(curr_script)[0]
1
ab09b8a10876 Added trivial half-baked implementation of securable modules.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
523
6
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
524 if (not path.startswith(".") or
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
525 not curr_dir.startswith(self.root_dir)):
4
ae5869491e61 Added more to securablemodule impl.
Atul Varma <varmaa@toolness.com>
parents: 3
diff changeset
526 curr_dir = self.root_dir
6
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
527 ospath = path.replace('/', os.path.sep)
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
528 filename = os.path.join(curr_dir, "%s.js" % ospath)
2
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
529 filename = os.path.normpath(filename)
3
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
530 if (not filename.startswith(self.root_dir) or
2
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
531 not (os.path.exists(filename) and
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
532 not os.path.isdir(filename))):
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
533 raise pydermonkey.error('Module not found: %s' % path)
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
534
3
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
535 if filename not in self.modules:
4
ae5869491e61 Added more to securablemodule impl.
Atul Varma <varmaa@toolness.com>
parents: 3
diff changeset
536 self._load_module(filename)
3
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
537 return self.modules[filename]
2
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
538
6
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
539 def run_test(name, libpath):
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
540 print name
3
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
541 sandbox = JsSandbox()
2
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
542
9
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
543 stats = [0, 0]
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
544
3
14d8d73774d7 Refactored securable module loader.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
545 @jsexposed(name='print')
6
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
546 def jsprint(message, label):
9
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
547 if label == "pass":
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
548 stats[0] += 1
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
549 elif label == "fail":
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
550 stats[1] += 1
6
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
551 print "%s %s" % (message, label)
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
552
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
553 system = sandbox.new_object()
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
554 system['print'] = jsprint
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
555 globals = {'sys': system,
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
556 'environment': sandbox.new_object()}
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
557 loader = SecurableModuleLoader(sandbox, libpath, globals)
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
558 retval = sandbox.run_script("require('program')")
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
559 sandbox.finish()
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
560 print
9
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
561
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
562 if retval != 0:
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
563 stats[1] += 1
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
564 return stats
2
b6f9d743a2b5 Refined require() implementation.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
565
6
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
566 if __name__ == '__main__':
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
567 base_libpath = os.path.join("interoperablejs-read-only",
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
568 "compliance")
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
569 if not os.path.exists(base_libpath):
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
570 print "Please run the following command and then re-run "
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
571 print "this script:"
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
572 print
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
573 print ("svn checkout "
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
574 "http://interoperablejs.googlecode.com/svn/trunk/ "
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
575 "interoperablejs-read-only")
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
576 sys.exit(1)
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
577
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
578 dirs = [(os.path.join(base_libpath, name), name)
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
579 for name in os.listdir(base_libpath)
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
580 if name not in ['.svn', 'ORACLE']]
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
581
9
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
582 totals = [0, 0]
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
583
6
97adec8c8127 Now passing all CommonJS SecurableModule compliance tests.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
584 for libpath, name in dirs:
9
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
585 passed, failed = run_test(name, libpath)
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
586 totals[0] += passed
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
587 totals[1] += failed
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
588
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
589 print "passed: %d failed: %d" % tuple(totals)
5
c11c84274192 Added memory leak detection.
Atul Varma <varmaa@toolness.com>
parents: 4
diff changeset
590
c11c84274192 Added memory leak detection.
Atul Varma <varmaa@toolness.com>
parents: 4
diff changeset
591 import gc
c11c84274192 Added memory leak detection.
Atul Varma <varmaa@toolness.com>
parents: 4
diff changeset
592 gc.collect()
c11c84274192 Added memory leak detection.
Atul Varma <varmaa@toolness.com>
parents: 4
diff changeset
593 if pydermonkey.get_debug_info()['runtime_count']:
c11c84274192 Added memory leak detection.
Atul Varma <varmaa@toolness.com>
parents: 4
diff changeset
594 print "WARNING: JS runtime was not destroyed."
9
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
595
a88d1cc4db92 Test runner now displays # passed and failed.
Atul Varma <varmaa@toolness.com>
parents: 8
diff changeset
596 sys.exit(totals[1])