Ejemplo n.º 1
0
    def setOwner(self, owner):
        if self.owner is not None:
            return

        ParameterSpecTuple.setOwner( self, owner )

        if self.list_star_arg:
            self.list_star_variable = Variables.ParameterVariable( owner, self.list_star_arg, False )
        else:
            self.list_star_variable = None

        if self.dict_star_arg:
            self.dict_star_variable = Variables.ParameterVariable(
                owner          = owner,
                parameter_name = self.dict_star_arg,
                kw_only        = False
            )
        else:
            self.dict_star_variable = None

        self.kw_only_variables = [
            Variables.ParameterVariable( self.owner, kw_only_arg, True )
            for kw_only_arg in
            self.kw_only_args
        ]
Ejemplo n.º 2
0
    def setOwner(self, owner):
        if self.owner is not None:
            return

        self.owner = owner
        self.normal_variables = []

        for normal_arg in self.normal_args:
            if type(normal_arg) is str:
                normal_variable = Variables.ParameterVariable(
                    owner=self.owner, parameter_name=normal_arg)
            else:
                assert False, normal_arg

            self.normal_variables.append(normal_variable)

        if self.list_star_arg:
            self.list_star_variable = Variables.ParameterVariable(
                owner=owner, parameter_name=self.list_star_arg)
        else:
            self.list_star_variable = None

        if self.dict_star_arg:
            self.dict_star_variable = Variables.ParameterVariable(
                owner=owner, parameter_name=self.dict_star_arg)
        else:
            self.dict_star_variable = None

        self.kw_only_variables = [
            Variables.ParameterVariable(owner=self.owner,
                                        parameter_name=kw_only_arg)
            for kw_only_arg in self.kw_only_args
        ]
Ejemplo n.º 3
0
    def setOwner(self, owner):
        assert self.owner is None

        self.owner = owner

        self.normal_variables = []

        for count, normal_arg in enumerate( self.normal_args ):
            if type( normal_arg ) == str:
                normal_variable = Variables.ParameterVariable(
                    owner          = self.owner,
                    parameter_name = normal_arg,
                    kw_only        = False
                )
            elif type( normal_arg ) == tuple:
                sub_parameter_spec = ParameterSpecTuple(
                    normal_args = normal_arg,
                    nest_count  = self.nest_count + 1
                )
                sub_parameter_spec.setOwner( self.owner )

                sub_parameter_name = "Unpackable_%s_%s" % (
                    self.nest_count,
                    count+1
                )

                normal_variable = Variables.NestedParameterVariable(
                    owner          = self.owner,
                    parameter_name = sub_parameter_name,
                    parameter_spec = sub_parameter_spec
                )
            else:
                assert False, normal_arg

            self.normal_variables.append( normal_variable )
Ejemplo n.º 4
0
def makeOptimizationPass():
    """Make a single pass for optimization, indication potential completion."""

    # Controls complex optimization

    finished = True

    ModuleRegistry.startTraversal()

    _restartProgress()

    while True:
        current_module = ModuleRegistry.nextModule()

        if current_module is None:
            break

        _traceProgress(current_module)

        # The tag set is global, so it can react to changes without context.
        # pylint: disable=global-statement
        global tag_set
        tag_set = TagSet()

        changed = optimizeModule(current_module)

        if changed:
            finished = False

    # Unregister collection traces from now unused code, dropping the trace
    # collections of functions no longer used. This must be done after global
    # optimization due to cross module usages.
    for current_module in ModuleRegistry.getDoneModules():
        if current_module.isCompiledPythonModule():
            for unused_function in current_module.getUnusedFunctions():
                Variables.updateVariablesFromCollection(
                    old_collection=unused_function.trace_collection,
                    new_collection=None,
                    source_ref=unused_function.getSourceReference(),
                )

                unused_function.trace_collection = None

            used_functions = tuple(
                function
                for function in current_module.subnode_functions
                if function in current_module.getUsedFunctions()
            )

            current_module.setChild("functions", used_functions)

    _endProgress()

    return finished
Ejemplo n.º 5
0
def makeOptimizationPass():
    """Make a single pass for optimization, indication potential completion."""

    # Controls complex optimization

    finished = True

    ModuleRegistry.startTraversal()

    _restartProgress()

    while True:
        current_module = ModuleRegistry.nextModule()

        if current_module is None:
            # TODO: Internal module seems to cause extra passes.
            # optimizeModule(getInternalModule())
            break

        _traceProgressModuleStart(current_module)

        changed = optimizeModule(current_module)

        _traceProgressModuleEnd(current_module)

        if changed:
            finished = False

    # Unregister collection traces from now unused code, dropping the trace
    # collections of functions no longer used. This must be done after global
    # optimization due to cross module usages.
    for current_module in ModuleRegistry.getDoneModules():
        if current_module.isCompiledPythonModule():
            for unused_function in current_module.getUnusedFunctions():
                Variables.updateVariablesFromCollection(
                    old_collection=unused_function.trace_collection,
                    new_collection=None,
                    source_ref=unused_function.getSourceReference(),
                )

                unused_function.trace_collection = None

            used_functions = tuple(
                function
                for function in current_module.subnode_functions
                if function in current_module.getUsedFunctions()
            )

            current_module.setChild("functions", used_functions)

    _endProgress()

    return finished
Ejemplo n.º 6
0
def makeOptimizationPass(initial_pass):
    """ Make a single pass for optimization, indication potential completion.

    """
    finished = True

    ModuleRegistry.startTraversal()

    if _progress:
        if initial_pass:
            info("Initial optimization pass.")
        else:
            info("Next global optimization pass.")

    while True:
        current_module = ModuleRegistry.nextModule()

        if current_module is None:
            break

        if _progress:
            _traceProgress(current_module)

        # The tag set is global, so it can react to changes without context.
        # pylint: disable=global-statement
        global tag_set
        tag_set = TagSet()

        changed = optimizeModule(current_module)

        if changed:
            finished = False

    # Unregister collection traces from now unused code, dropping the trace
    # collections of functions no longer used.
    for current_module in ModuleRegistry.getDoneModules():
        if current_module.isCompiledPythonModule():
            for function in current_module.getUnusedFunctions():
                Variables.updateFromCollection(
                    old_collection=function.trace_collection,
                    new_collection=None)

                function.trace_collection = None

    for current_module in ModuleRegistry.getDoneModules():
        if optimizeVariables(current_module):
            finished = False

    return finished
Ejemplo n.º 7
0
def makeOptimizationPass(initial_pass):
    """ Make a single pass for optimization, indication potential completion.

    """
    finished = True

    ModuleRegistry.startTraversal()

    if _progress:
        if initial_pass:
            printLine("Initial optimization pass.")
        else:
            printLine("Next global optimization pass.")

    while True:
        current_module = ModuleRegistry.nextModule()

        if current_module is None:
            break

        if _progress:
            _traceProgress(current_module)

        # The tag set is global, so it can react to changes without context.
        # pylint: disable=W0603
        global tag_set
        tag_set = TagSet()

        changed = optimizeModule(current_module)

        if changed:
            finished = False

    # Unregister collection traces from now unused code, dropping the trace
    # collections of functions no longer used.
    for current_module in ModuleRegistry.getDoneModules():
        if current_module.isCompiledPythonModule():
            for function in current_module.getUnusedFunctions():
                Variables.updateFromCollection(
                    old_collection = function.trace_collection,
                    new_collection = None
                )

                function.trace_collection = None

    for current_module in ModuleRegistry.getDoneModules():
        optimizeVariables(current_module)

    return finished
Ejemplo n.º 8
0
    def allocateTempVariable(self, temp_scope, name):
        if temp_scope is not None:
            full_name = "%s__%s" % (
                temp_scope,
                name
            )
        else:
            assert name != "result"

            full_name = name

        del name

        assert full_name not in self.temp_variables, full_name

        result = Variables.TempVariable(
            owner         = self,
            variable_name = full_name
        )

        self.temp_variables[full_name] = result

        addVariableUsage(result, self)

        return result
Ejemplo n.º 9
0
    def getLocalVariable(self, owner, variable_name):
        if variable_name not in self.local_variables:
            result = Variables.LocalVariable(owner=owner, variable_name=variable_name)

            self.local_variables[variable_name] = result

        return self.local_variables[variable_name]
Ejemplo n.º 10
0
def _optimizeModulePass(module, tag_set):
    def signalChange(tags, source_ref, message):
        """ Indicate a change to the optimization framework.

        """
        debug("%s : %s : %s" % (source_ref.getAsString(), tags, message))

        tag_set.onSignal(tags)

    constraint_collection = ConstraintCollectionModule(signalChange)
    constraint_collection.process(module=module)

    written_variables = constraint_collection.getWrittenVariables()

    for variable in Variables.getModuleVariables(module=module):
        old_value = variable.getReadOnlyIndicator()
        new_value = variable not in written_variables

        if old_value is not new_value and new_value:
            # Don't suddenly start to write.
            assert not (new_value is False and old_value is True)

            constraint_collection.signalChange(
                "read_only_mvar", module.getSourceReference(),
                "Determined variable '%s' is only read." % variable.getName())

            variable.setReadOnlyIndicator(new_value)
Ejemplo n.º 11
0
def _optimizeModulePass( module, tag_set ):
    def signalChange( tags, source_ref, message ):
        """ Indicate a change to the optimization framework.

        """
        debug( "%s : %s : %s" % ( source_ref.getAsString(), tags, message ) )

        tag_set.onSignal( tags )

    constraint_collection = ConstraintCollectionModule( signalChange )
    constraint_collection.process( module = module )

    written_variables = constraint_collection.getWrittenVariables()

    for variable in Variables.getModuleVariables( module = module ):
        old_value = variable.getReadOnlyIndicator()
        new_value = variable not in written_variables

        if old_value is not new_value and new_value:
            # Don't suddenly start to write.
            assert not (new_value is False and old_value is True)

            constraint_collection.signalChange(
                "read_only_mvar",
                module.getSourceReference(),
                "Determined variable '%s' is only read." % variable.getName()
            )

            variable.setReadOnlyIndicator( new_value )
Ejemplo n.º 12
0
    def createProvidedVariable(self, variable_name):
        # print("createProvidedVariable", self, variable_name)

        return Variables.LocalVariable(
            owner         = self,
            variable_name = variable_name
        )
Ejemplo n.º 13
0
    def createProvidedVariable(self, variable_name):
        # print( "createProvidedVariable", self, variable_name )

        if self.local_locals:
            if self.isClassDictCreation():
                return Variables.ClassVariable(owner=self,
                                               variable_name=variable_name)
            else:
                return Variables.LocalVariable(owner=self,
                                               variable_name=variable_name)
        else:
            # Make sure the provider knows it has to provide a variable of this
            # name for the assigment.
            self.provider.getVariableForAssignment(variable_name=variable_name)

            return self.getClosureVariable(variable_name=variable_name)
Ejemplo n.º 14
0
    def getVariableForReference(self, variable_name):
        # print ( "REF func", self, variable_name )

        if self.hasProvidedVariable(variable_name):
            result = self.getProvidedVariable(variable_name)
        else:
            result = self.getClosureVariable(
                variable_name = variable_name
            )

            # Remember that we need that closure variable for something, so
            # we don't create it again all the time.
            if not result.isModuleVariable():
                self.registerProvidedVariable(result)

            # For "exec" containing/star import containing, we get a
            # closure variable already, but if it is a module variable,
            # only then make it a maybe local variable.
            if self.isUnoptimized() and result.isModuleVariable():
                result = Variables.MaybeLocalVariable(
                    owner          = self,
                    maybe_variable = result
                )

                self.registerProvidedVariable(result)

        return result
Ejemplo n.º 15
0
    def getLocalsDictVariable(self, variable_name):
        if variable_name not in self.variables:
            result = Variables.LocalsDictVariable(owner=self,
                                                  variable_name=variable_name)

            self.variables[variable_name] = result

        return self.variables[variable_name]
Ejemplo n.º 16
0
    def createProvidedVariable(self, variable_name):
        assert variable_name not in self.variables

        result = Variables.ModuleVariable(module=self, variable_name=variable_name)

        self.variables[variable_name] = result

        return result
Ejemplo n.º 17
0
    def createProvidedVariable(self, variable_name):
        result = Variables.ModuleVariable(module=self,
                                          variable_name=variable_name)

        assert result not in self.variables
        self.variables.add(result)

        return result
Ejemplo n.º 18
0
    def getTempVariable(self, name):
        assert name not in self.temp_variables, name

        result = Variables.TempVariable(owner=self, variable_name=name)

        self.temp_variables[name] = result

        return result
Ejemplo n.º 19
0
    def allocateTempKeeperVariable(self):
        name = "keeper_%d" % len(self.keeper_variables)

        result = Variables.TempKeeperVariable(owner=self, variable_name=name)

        self.keeper_variables.add(result)

        return result
Ejemplo n.º 20
0
    def createTempVariable(self, temp_name):
        if temp_name in self.temp_variables:
            return self.temp_variables[temp_name]

        result = Variables.TempVariable(owner=self, variable_name=temp_name)

        self.temp_variables[temp_name] = result

        return result
Ejemplo n.º 21
0
    def getTempKeeperVariable(self):
        name = "keeper_%d" % len(self.keeper_variables)

        from nuitka import Variables

        result = Variables.TempKeeperVariable(owner=self, variable_name=name)

        self.keeper_variables.add(result)

        return result
Ejemplo n.º 22
0
    def demoteClosureVariable(self, variable):
        assert variable.isLocalVariable()

        self.taken.remove(variable)

        assert variable.getOwner() is not self

        new_variable = Variables.LocalVariable(
            owner=self, variable_name=variable.getName())

        self.providing[variable.getName()] = new_variable

        updateVariableUsage(provider=self,
                            old_variable=variable,
                            new_variable=new_variable)

        VariableRegistry.addVariableUsage(new_variable, self)
Ejemplo n.º 23
0
    def getVariableForReference(self, variable_name):
        # print ( "REF func", self, variable_name )

        if self.hasProvidedVariable(variable_name):
            result = self.getProvidedVariable(variable_name)
        else:
            # For exec containing/star import containing, get a closure variable
            # and if it is a module variable, only then make it a maybe local
            # variable.
            result = self.getClosureVariable(variable_name=variable_name)

            if self.isUnoptimized() and result.isModuleVariable():
                result = Variables.MaybeLocalVariable(
                    owner=self, variable_name=variable_name)

            # Remember that we need that closure for something.
            self.registerProvidedVariable(result)

        return result
Ejemplo n.º 24
0
    def demoteClosureVariable(self, variable):
        assert variable.isLocalVariable()

        self.taken.remove(variable)

        assert variable.getOwner() is not self

        new_variable = Variables.LocalVariable(
            owner=self, variable_name=variable.getName())
        for variable_trace in variable.traces:
            if variable_trace.getOwner() is self:
                new_variable.addTrace(variable_trace)
        new_variable.updateUsageState()

        self.providing[variable.getName()] = new_variable

        updateVariableUsage(provider=self,
                            old_variable=variable,
                            new_variable=new_variable)
Ejemplo n.º 25
0
 def updateVariablesFromCollection(self, old_collection, source_ref):
     Variables.updateVariablesFromCollection(old_collection, self, source_ref)
Ejemplo n.º 26
0
 def updateVariablesFromCollection(self, old_collection):
     Variables.updateVariablesFromCollection(old_collection, self)
Ejemplo n.º 27
0
 def updateVariablesFromCollection(self, old_collection):
     Variables.updateVariablesFromCollection(old_collection, self)
Ejemplo n.º 28
0
def makeOptimizationPass(initial_pass):
    """ Make a single pass for optimization, indication potential completion.

    """
    # Controls complex optimization, pylint: disable=too-many-branches

    finished = True

    ModuleRegistry.startTraversal()

    if _progress:
        if initial_pass:
            info("Initial optimization pass.")
        else:
            info("Next global optimization pass.")

    while True:
        current_module = ModuleRegistry.nextModule()

        if current_module is None:
            break

        if _progress:
            _traceProgress(current_module)

        # The tag set is global, so it can react to changes without context.
        # pylint: disable=global-statement
        global tag_set
        tag_set = TagSet()

        changed = optimizeModule(current_module)

        if changed:
            finished = False

    # Unregister collection traces from now unused code, dropping the trace
    # collections of functions no longer used.
    for current_module in ModuleRegistry.getDoneModules():
        if current_module.isCompiledPythonModule():
            for function in current_module.getUnusedFunctions():
                Variables.updateVariablesFromCollection(
                    old_collection=function.trace_collection, new_collection=None
                )

                function.trace_collection = None

    for current_module in ModuleRegistry.getDoneModules():
        if current_module.isCompiledPythonModule():
            if optimizeVariables(current_module):
                finished = False

            used_functions = current_module.getUsedFunctions()

            for unused_function in current_module.getUnusedFunctions():
                unused_function.trace_collection = None

            used_functions = tuple(
                function
                for function in current_module.getFunctions()
                if function in used_functions
            )

            current_module.setFunctions(used_functions)

    if Variables.complete:
        if optimizeLocalsDictsHandles():
            finished = False

    return finished
Ejemplo n.º 29
0
 def getLocalVariableNames(self):
     return Variables.getNames(self.getLocalVariables())
Ejemplo n.º 30
0
 def getParameterNames(self):
     return Variables.getNames(self.getVariables())
Ejemplo n.º 31
0
    def onEnterNode(self, node):
        # Mighty complex code with lots of branches and statements, but it
        # couldn't be less without making it more difficult.
        # pylint: disable=R0912,R0915

        if node.isExpressionTargetVariableRef():
            provider = node.getParentVariableProvider()

            if node.getVariable() is None:
                variable_name = node.getVariableName()

                variable = provider.getVariableForAssignment(
                    variable_name=variable_name)

                node.setVariable(variable)

            addVariableUsage(node.getVariable(), provider)
        elif node.isExpressionTargetTempVariableRef():
            provider = node.getParentVariableProvider()

            addVariableUsage(node.getVariable(), provider)
        elif node.isExpressionVariableRef():
            if node.getVariable() is None:
                provider = node.getParentVariableProvider()

                if provider.isEarlyClosure():
                    variable = provider.getVariableForReference(
                        variable_name=node.getVariableName())

                    # Python3.4 version respects closure variables taken can be
                    # overridden by writes to locals. It should be done for
                    # globals too, on all versions, but for Python2 the locals
                    # dictionary is avoided unless "exec" appears, so it's not
                    # done.
                    if variable.getOwner() is not provider:
                        if python_version >= 340 or \
                           (python_version >= 300 and \
                            variable.isModuleVariable()):
                            variable = Variables.MaybeLocalVariable(
                                owner=provider, maybe_variable=variable)

                    node.setVariable(variable)
        elif node.isExpressionTempVariableRef():
            if node.getVariable().getOwner() != node.getParentVariableProvider(
            ):
                node.setVariable(
                    node.getParentVariableProvider().addClosureVariable(
                        node.getVariable()))
        elif node.isExpressionFunctionBody():
            if python_version >= 300:
                self._handleNonLocal(node)

            for variable in node.getParameters().getAllVariables():
                addVariableUsage(variable, node)

            # Python3.4 allows for class declarations to be made global, even
            # after they were declared, so we need to fix this up.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        # Attribute access of names of class functions should be mangled, if
        # they start with "__", but do not end in "__" as well.
        elif node.isExpressionAttributeLookup() or \
             node.isStatementAssignmentAttribute() or \
             node.isStatementDelAttribute():
            attribute_name = node.getAttributeName()

            if attribute_name.startswith("__") and \
               not attribute_name.endswith("__"):
                seen_function = False

                current = node

                while True:
                    current = current.getParentVariableProvider()

                    if current.isPythonModule():
                        break

                    assert current.isExpressionFunctionBody()

                    if current.isClassDictCreation():
                        if seen_function:
                            node.setAttributeName(
                                "_%s%s" % (current.getName().lstrip("_"),
                                           attribute_name))

                        break
                    else:
                        seen_function = True
        # Check if continue and break are properly in loops. If not, raise a
        # syntax error.
        elif node.isStatementBreakLoop() or node.isStatementContinueLoop():
            current = node

            while True:
                if current.isPythonModule() or \
                   current.isExpressionFunctionBody():
                    if node.isStatementContinueLoop():
                        message = "'continue' not properly in loop"
                        col_offset = 16 if python_version >= 300 else None
                        display_line = True
                        source_line = None
                    else:
                        message = "'break' outside loop"

                        if isFullCompat():
                            col_offset = 2 if python_version >= 300 else None
                            display_line = True
                            source_line = "" if python_version >= 300 else None
                        else:
                            col_offset = 13
                            display_line = True
                            source_line = None

                    SyntaxErrors.raiseSyntaxError(
                        message,
                        source_ref=node.getSourceReference(),
                        col_offset=col_offset,
                        display_line=display_line,
                        source_line=source_line)

                current = current.getParent()

                if current.isStatementLoop():
                    break
 def mangle(variable_name):
     return Variables.mangleName(variable_name, provider)
Ejemplo n.º 33
0
 def getParameterNames(self):
     return Variables.getNames(self.getVariables())
Ejemplo n.º 34
0
def makeOptimizationPass():
    """Make a single pass for optimization, indication potential completion."""
    # Controls complex optimization, pylint: disable=too-many-branches

    finished = True

    ModuleRegistry.startTraversal()

    while True:
        current_module = ModuleRegistry.nextModule()

        if current_module is None:
            break

        if _progress:
            _traceProgress(current_module)

        # The tag set is global, so it can react to changes without context.
        # pylint: disable=global-statement
        global tag_set
        tag_set = TagSet()

        changed = optimizeModule(current_module)

        if changed:
            finished = False

    # Unregister collection traces from now unused code, dropping the trace
    # collections of functions no longer used.
    for current_module in ModuleRegistry.getDoneModules():
        if current_module.isCompiledPythonModule():
            for function in current_module.getUnusedFunctions():
                Variables.updateVariablesFromCollection(
                    old_collection=function.trace_collection,
                    new_collection=None,
                    source_ref=function.getSourceReference(),
                )

                function.trace_collection = None

    for current_module in ModuleRegistry.getDoneModules():
        if current_module.isCompiledPythonModule():
            if optimizeVariables(current_module):
                finished = False

            used_functions = current_module.getUsedFunctions()

            for unused_function in current_module.getUnusedFunctions():
                unused_function.trace_collection = None

            used_functions = tuple(
                function for function in current_module.getFunctions()
                if function in used_functions)

            current_module.setFunctions(used_functions)

    if Variables.complete:
        if optimizeLocalsDictsHandles():
            finished = False

    return finished