comparison pydertron.py @ 2:b6f9d743a2b5

Refined require() implementation.
author Atul Varma <varmaa@toolness.com>
date Wed, 09 Sep 2009 21:48:49 -0700
parents ab09b8a10876
children 14d8d73774d7
comparison
equal deleted inserted replaced
1:ab09b8a10876 2:b6f9d743a2b5
234 """ 234 """
235 235
236 def __init__(self, root_dir, watchdog=watchdog): 236 def __init__(self, root_dir, watchdog=watchdog):
237 rt = pydermonkey.Runtime() 237 rt = pydermonkey.Runtime()
238 cx = rt.new_context() 238 cx = rt.new_context()
239 root = cx.new_object() 239 root_proto = cx.new_object()
240 cx.init_standard_classes(root) 240 cx.init_standard_classes(root_proto)
241 root = cx.new_object(None, root_proto)
241 242
242 cx.set_operation_callback(self._opcb) 243 cx.set_operation_callback(self._opcb)
243 cx.set_throw_hook(self._throwhook) 244 cx.set_throw_hook(self._throwhook)
244 watchdog.add_context(cx) 245 watchdog.add_context(cx)
245 246
249 self.curr_exc = None 250 self.curr_exc = None
250 self.py_stack = None 251 self.py_stack = None
251 self.js_stack = None 252 self.js_stack = None
252 self.__py_to_js = {} 253 self.__py_to_js = {}
253 self.__type_protos = {} 254 self.__type_protos = {}
255 self.root_proto = root_proto
254 self.root = self.wrap_jsobject(root, root) 256 self.root = self.wrap_jsobject(root, root)
255 257
256 def finish(self): 258 def finish(self):
257 """ 259 """
258 Cleans up all resources used by the sandbox, breaking any reference 260 Cleans up all resources used by the sandbox, breaking any reference
470 472
471 if __name__ == '__main__': 473 if __name__ == '__main__':
472 import os 474 import os
473 sandbox = JsSandbox("modules") 475 sandbox = JsSandbox("modules")
474 476
475 @jsexposed(on=sandbox.root, name='print') 477 modules = {}
478
479 @jsexposed(name='print')
476 def jsprint(string): 480 def jsprint(string):
477 print string 481 print string
478 482
479 @jsexposed(on=sandbox.root) 483 @jsexposed
480 def require(path): 484 def require(path):
481 mcx = sandbox.rt.new_context() 485 cx = sandbox.cx
482 module = mcx.new_object() 486 frame = cx.get_stack()['caller']
483 mcx.init_standard_classes(module) 487 curr_script = None
484 exports = mcx.new_object() 488 while frame and curr_script is None:
485 mcx.define_property(module, 'exports', exports) 489 if frame['function'] and frame['function'].filename:
486 490 curr_script = frame['function'].filename
487 wrappedmodule = sandbox.wrap_jsobject(module) 491 elif frame['script']:
488 wrappedmodule['print'] = jsprint 492 curr_script = frame['script'].filename
489 wrappedmodule['require'] = require 493 frame = frame['caller']
490 494
491 filename = os.path.join(sandbox.root_dir, "%s.js" % path) 495 if curr_script is None:
492 contents = open(filename).read() 496 raise RuntimeError("Can't find calling script")
493 mcx.evaluate_script(module, contents, filename, 1) 497
494 return sandbox.wrap_jsobject(exports) 498 curr_dir = os.path.split(curr_script)[0]
495 499
500 filename = os.path.join(sandbox.root_dir, curr_dir, "%s.js" % path)
501 filename = os.path.normpath(filename)
502 if (not filename.startswith(sandbox.root_dir) or
503 not (os.path.exists(filename) and
504 not os.path.isdir(filename))):
505 raise pydermonkey.error('Module not found: %s' % path)
506
507 if filename not in modules:
508 module = cx.new_object(None, sandbox.root_proto)
509 cx.init_standard_classes(module)
510 exports = cx.new_object()
511 cx.define_property(module, 'exports', exports)
512
513 install_globals(sandbox.wrap_jsobject(module))
514
515 contents = open(filename).read()
516 cx.evaluate_script(module, contents, filename, 1)
517 modules[filename] = sandbox.wrap_jsobject(exports)
518
519 return modules[filename]
520
521 def install_globals(target):
522 target['print'] = jsprint
523 target['require'] = require
524
525 install_globals(sandbox.root)
496 sandbox.run_script('test.js') 526 sandbox.run_script('test.js')
497 sandbox.finish() 527 sandbox.finish()