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