Mercurial > pydertron
changeset 3:14d8d73774d7
Refactored securable module loader.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Wed, 09 Sep 2009 22:01:43 -0700 |
parents | b6f9d743a2b5 |
children | ae5869491e61 |
files | pydertron.py |
diffstat | 1 files changed, 46 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/pydertron.py Wed Sep 09 21:48:49 2009 -0700 +++ b/pydertron.py Wed Sep 09 22:01:43 2009 -0700 @@ -233,7 +233,7 @@ loading and executing scripts. """ - def __init__(self, root_dir, watchdog=watchdog): + def __init__(self, watchdog=watchdog): rt = pydermonkey.Runtime() cx = rt.new_context() root_proto = cx.new_object() @@ -244,7 +244,6 @@ cx.set_throw_hook(self._throwhook) watchdog.add_context(cx) - self.root_dir = root_dir self.rt = rt self.cx = cx self.curr_exc = None @@ -470,20 +469,21 @@ print e.exc_info[1] return retval -if __name__ == '__main__': - import os - sandbox = JsSandbox("modules") - - modules = {} +class SecurableModuleLoader(object): + def __init__(self, sandbox, root_dir, globals): + self.root_dir = root_dir + self.sandbox = sandbox + self.globals = globals + self.modules = {} + self._install_globals(sandbox.root) - @jsexposed(name='print') - def jsprint(string): - print string + def _install_globals(self, object): + for name in self.globals: + object[name] = self.globals[name] + object['require'] = self.require - @jsexposed - def require(path): - cx = sandbox.cx - frame = cx.get_stack()['caller'] + def _get_calling_script(self): + frame = self.sandbox.cx.get_stack()['caller'] curr_script = None while frame and curr_script is None: if frame['function'] and frame['function'].filename: @@ -494,34 +494,48 @@ if curr_script is None: raise RuntimeError("Can't find calling script") + return curr_script + def _load_module(self, filename): + sandbox = self.sandbox + cx = sandbox.cx + + module = cx.new_object(None, sandbox.root_proto) + cx.init_standard_classes(module) + exports = cx.new_object() + cx.define_property(module, 'exports', exports) + + self._install_globals(sandbox.wrap_jsobject(module)) + + contents = open(filename).read() + cx.evaluate_script(module, contents, filename, 1) + return sandbox.wrap_jsobject(exports) + + @jsexposed + def require(self, path): + curr_script = self._get_calling_script() curr_dir = os.path.split(curr_script)[0] - filename = os.path.join(sandbox.root_dir, curr_dir, "%s.js" % path) + filename = os.path.join(self.root_dir, curr_dir, "%s.js" % path) filename = os.path.normpath(filename) - if (not filename.startswith(sandbox.root_dir) or + if (not filename.startswith(self.root_dir) or not (os.path.exists(filename) and not os.path.isdir(filename))): raise pydermonkey.error('Module not found: %s' % path) - if filename not in modules: - module = cx.new_object(None, sandbox.root_proto) - cx.init_standard_classes(module) - exports = cx.new_object() - cx.define_property(module, 'exports', exports) - - install_globals(sandbox.wrap_jsobject(module)) + if filename not in self.modules: + self.modules[filename] = self._load_module(filename) + return self.modules[filename] - contents = open(filename).read() - cx.evaluate_script(module, contents, filename, 1) - modules[filename] = sandbox.wrap_jsobject(exports) - - return modules[filename] +if __name__ == '__main__': + import os + sandbox = JsSandbox() - def install_globals(target): - target['print'] = jsprint - target['require'] = require + @jsexposed(name='print') + def jsprint(string): + print string - install_globals(sandbox.root) + globals = {'print': jsprint} + loader = SecurableModuleLoader(sandbox, "modules", globals) sandbox.run_script('test.js') sandbox.finish()