Mercurial > pydertron
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() |