# HG changeset patch # User Atul Varma # Date 1252558129 25200 # Node ID b6f9d743a2b5a94d61faf10abb20c0d7314a13cc # Parent ab09b8a10876ed6324934d9cb91bc15c46199cad Refined require() implementation. diff -r ab09b8a10876 -r b6f9d743a2b5 modules/foo.js --- a/modules/foo.js Wed Sep 09 21:09:39 2009 -0700 +++ b/modules/foo.js Wed Sep 09 21:48:49 2009 -0700 @@ -1,3 +1,5 @@ exports.bar = function bar() { print('hay!'); }; + +print('loading foo'); diff -r ab09b8a10876 -r b6f9d743a2b5 pydertron.py --- a/pydertron.py Wed Sep 09 21:09:39 2009 -0700 +++ b/pydertron.py Wed Sep 09 21:48:49 2009 -0700 @@ -236,8 +236,9 @@ def __init__(self, root_dir, watchdog=watchdog): rt = pydermonkey.Runtime() cx = rt.new_context() - root = cx.new_object() - cx.init_standard_classes(root) + root_proto = cx.new_object() + cx.init_standard_classes(root_proto) + root = cx.new_object(None, root_proto) cx.set_operation_callback(self._opcb) cx.set_throw_hook(self._throwhook) @@ -251,6 +252,7 @@ self.js_stack = None self.__py_to_js = {} self.__type_protos = {} + self.root_proto = root_proto self.root = self.wrap_jsobject(root, root) def finish(self): @@ -472,26 +474,54 @@ import os sandbox = JsSandbox("modules") - @jsexposed(on=sandbox.root, name='print') + modules = {} + + @jsexposed(name='print') def jsprint(string): print string - @jsexposed(on=sandbox.root) + @jsexposed def require(path): - mcx = sandbox.rt.new_context() - module = mcx.new_object() - mcx.init_standard_classes(module) - exports = mcx.new_object() - mcx.define_property(module, 'exports', exports) + cx = sandbox.cx + frame = cx.get_stack()['caller'] + curr_script = None + while frame and curr_script is None: + if frame['function'] and frame['function'].filename: + curr_script = frame['function'].filename + elif frame['script']: + curr_script = frame['script'].filename + frame = frame['caller'] + + if curr_script is None: + raise RuntimeError("Can't find calling script") + + curr_dir = os.path.split(curr_script)[0] - wrappedmodule = sandbox.wrap_jsobject(module) - wrappedmodule['print'] = jsprint - wrappedmodule['require'] = require + filename = os.path.join(sandbox.root_dir, curr_dir, "%s.js" % path) + filename = os.path.normpath(filename) + if (not filename.startswith(sandbox.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) - filename = os.path.join(sandbox.root_dir, "%s.js" % path) - contents = open(filename).read() - mcx.evaluate_script(module, contents, filename, 1) - return sandbox.wrap_jsobject(exports) + install_globals(sandbox.wrap_jsobject(module)) + + contents = open(filename).read() + cx.evaluate_script(module, contents, filename, 1) + modules[filename] = sandbox.wrap_jsobject(exports) + return modules[filename] + + def install_globals(target): + target['print'] = jsprint + target['require'] = require + + install_globals(sandbox.root) sandbox.run_script('test.js') sandbox.finish() diff -r ab09b8a10876 -r b6f9d743a2b5 test.js --- a/test.js Wed Sep 09 21:09:39 2009 -0700 +++ b/test.js Wed Sep 09 21:48:49 2009 -0700 @@ -2,4 +2,8 @@ foo.bar(); +foo = require('foo'); + +foo.bar(); + print('hello');