10
|
1 import sys
|
|
2 import time
|
|
3 import threading
|
|
4 import traceback
|
|
5 import pydermonkey
|
|
6
|
|
7 rt = pydermonkey.Runtime()
|
|
8 cx = rt.new_context()
|
|
9 globalobj = cx.new_object()
|
|
10 cx.init_standard_classes(globalobj)
|
|
11
|
|
12 def foo(cx, this, args):
|
|
13 return cx.call_function(this, args[0], ())
|
|
14
|
|
15 cx.define_property(globalobj,
|
|
16 'foo',
|
|
17 cx.new_function(foo, 'foo'))
|
|
18
|
|
19 def jsprint(cx, this, args):
|
|
20 if len(args) > 0:
|
|
21 print args[0]
|
|
22
|
|
23 cx.define_property(globalobj,
|
|
24 'print',
|
|
25 cx.new_function(jsprint, 'print'))
|
|
26
|
|
27 def opcb(cx):
|
|
28 # Don't do anything; if a keyboard interrupt was triggered,
|
|
29 # it'll get raised here automatically.
|
|
30 pass
|
|
31
|
|
32 cx.set_operation_callback(opcb)
|
|
33
|
|
34 class State(object):
|
|
35 def __init__(self):
|
|
36 self.curr_exc = None
|
|
37 self.curr_tb = None
|
|
38 self.curr_js_stack = None
|
|
39
|
|
40 state = State()
|
|
41
|
|
42 def throwhook(cx):
|
|
43 curr_exc = cx.get_pending_exception()
|
|
44 if state.curr_exc != curr_exc:
|
|
45 state.curr_exc = curr_exc
|
|
46 state.py_stack = traceback.extract_stack()
|
|
47 state.js_stack = cx.get_stack()
|
|
48
|
|
49 cx.set_throw_hook(throwhook)
|
|
50
|
|
51 def watchdog():
|
|
52 while 1:
|
|
53 time.sleep(0.25)
|
|
54 cx.trigger_operation_callback()
|
|
55
|
|
56 thread = threading.Thread(target=watchdog)
|
|
57 thread.setDaemon(True)
|
|
58 thread.start()
|
|
59
|
|
60 filename = 'test.js'
|
|
61
|
|
62 def make_stack(js_stack):
|
|
63 lines = []
|
|
64 while js_stack:
|
|
65 if js_stack['script']:
|
|
66 script = js_stack['script']
|
|
67 thing = dict(filename = script.filename,
|
|
68 lineno = js_stack['lineno'],
|
|
69 name = '<module>')
|
|
70 elif js_stack['function'] and not js_stack['function'].is_python:
|
|
71 func = js_stack['function']
|
|
72 thing = dict(filename = func.filename,
|
|
73 lineno = js_stack['lineno'],
|
|
74 name = func.name)
|
|
75 else:
|
|
76 thing = None
|
|
77 if thing:
|
|
78 lines.insert(0, " File \"%(filename)s\", line %(lineno)d, in %(name)s" % thing)
|
|
79 js_stack = js_stack['caller']
|
|
80 lines.insert(0, "Traceback (most recent call last):")
|
|
81 return '\n'.join(lines)
|
|
82
|
|
83 try:
|
|
84 cx.evaluate_script(globalobj, open(filename).read(), filename, 1)
|
|
85 except pydermonkey.error, e:
|
|
86 print make_stack(state.js_stack)
|
|
87 print e.args[1]
|