Bug 1132771 - Pass special types down to sandboxes via metadata; r=glandium
☠☠ backed out by ce21e7a57cf8 ☠ ☠
authorGregory Szorc <gps@mozilla.com>
Thu, 26 Feb 2015 09:43:55 -0800
changeset 261576 ed135df395751194bf379584a4d210f14ac849b4
parent 261575 acdd5491f10ecf8ea4e1a14150f9a2e282e2cf5d
child 261577 6c44edc8208a54a9d5d830266cded7b409a776e1
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium
bugs1132771
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1132771 - Pass special types down to sandboxes via metadata; r=glandium Currently, MozSandbox assumes that the FUNCTIONS, SPECIAL_VARIABLES, and SUBCONTEXTS data structures are the instances that should be associated with the sandbox. As we introduce new moz.build processing modes that wish to change processing behavior, it is necessary for them to have control over these special symbols. This patch moves the declaration of these types to the special metadata dictionary which is inherited during recursion. The "read_topsrcdir" API now explicitly passes the initial metadata into "read_mozbuild".
python/mozbuild/mozbuild/frontend/reader.py
--- a/python/mozbuild/mozbuild/frontend/reader.py
+++ b/python/mozbuild/mozbuild/frontend/reader.py
@@ -130,30 +130,35 @@ class MozbuildSandbox(Sandbox):
 
         self._log = logging.getLogger(__name__)
 
         self.metadata = dict(metadata)
         exports = self.metadata.get('exports', {})
         self.exports = set(exports.keys())
         context.update(exports)
         self.templates = self.metadata.setdefault('templates', {})
+        self.special_variables = self.metadata.setdefault('special_variables',
+                                                          SPECIAL_VARIABLES)
+        self.functions = self.metadata.setdefault('functions', FUNCTIONS)
+        self.subcontext_types = self.metadata.setdefault('subcontexts',
+                                                         SUBCONTEXTS)
 
     def __getitem__(self, key):
-        if key in SPECIAL_VARIABLES:
-            return SPECIAL_VARIABLES[key][0](self._context)
-        if key in FUNCTIONS:
-            return self._create_function(FUNCTIONS[key])
-        if key in SUBCONTEXTS:
-            return self._create_subcontext(SUBCONTEXTS[key])
+        if key in self.special_variables:
+            return self.special_variables[key][0](self._context)
+        if key in self.functions:
+            return self._create_function(self.functions[key])
+        if key in self.subcontext_types:
+            return self._create_subcontext(self.subcontext_types[key])
         if key in self.templates:
             return self._create_template_function(self.templates[key])
         return Sandbox.__getitem__(self, key)
 
     def __setitem__(self, key, value):
-        if key in SPECIAL_VARIABLES or key in FUNCTIONS or key in SUBCONTEXTS:
+        if key in self.special_variables or key in self.functions or key in self.subcontext_types:
             raise KeyError()
         if key in self.exports:
             self._context[key] = value
             self.exports.remove(key)
             return
         Sandbox.__setitem__(self, key, value)
 
     def exec_file(self, path):
@@ -351,22 +356,30 @@ class MozbuildSandbox(Sandbox):
         sandbox needs a function to execute. This is what this method returns.
         That function creates a new sandbox for execution of the template.
         After the template is executed, the data from its execution is merged
         with the context of the calling sandbox.
         """
         func, code, path = template
 
         def template_function(*args, **kwargs):
-            context = TemplateContext(VARIABLES, self._context.config)
+            context = TemplateContext(self._context._allowed_variables,
+                                      self._context.config)
             context.add_source(self._context.current_path)
             for p in self._context.all_paths:
                 context.add_source(p)
 
-            sandbox = MozbuildSandbox(context, {
+            sandbox = MozbuildSandbox(context, metadata={
+                # We should arguably set these defaults to something else.
+                # Templates, for example, should arguably come from the state
+                # of the sandbox from when the template was declared, not when
+                # it was instantiated. Bug 1137319.
+                'functions': self.metadata.get('functions', {}),
+                'special_variables': self.metadata.get('special_variables', {}),
+                'subcontexts': self.metadata.get('subcontexts', {}),
                 'templates': self.metadata.get('templates', {})
             })
             for k, v in inspect.getcallargs(func, *args, **kwargs).items():
                 sandbox[k] = v
 
             sandbox.exec_source(code, path)
 
             # This is gross, but allows the merge to happen. Eventually, the
@@ -1030,22 +1043,21 @@ class BuildReader(object):
         for var, var_dirs in dirs:
             for d in var_dirs:
                 if d in recurse_info:
                     raise SandboxValidationError(
                         'Directory (%s) registered multiple times in %s' % (
                             mozpath.relpath(d, context.srcdir), var), context)
 
                 recurse_info[d] = {}
-                if 'templates' in sandbox.metadata:
-                    recurse_info[d]['templates'] = dict(
-                        sandbox.metadata['templates'])
-                if 'exports' in sandbox.metadata:
-                    sandbox.recompute_exports()
-                    recurse_info[d]['exports'] = dict(sandbox.metadata['exports'])
+                for key in sandbox.metadata:
+                    if key == 'exports':
+                        sandbox.recompute_exports()
+
+                    recurse_info[d][key] = dict(sandbox.metadata[key])
 
         for path, child_metadata in recurse_info.items():
             child_path = path.join('moz.build')
 
             # Ensure we don't break out of the topsrcdir. We don't do realpath
             # because it isn't necessary. If there are symlinks in the srcdir,
             # that's not our problem. We're not a hosted application: we don't
             # need to worry about security too much.