Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1987)

Unified Diff: third_party/cython/src/Cython/Compiler/Pipeline.py

Issue 385073004: Adding cython v0.20.2 in third-party. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reference cython dev list thread. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/cython/src/Cython/Compiler/Pipeline.py
diff --git a/third_party/cython/src/Cython/Compiler/Pipeline.py b/third_party/cython/src/Cython/Compiler/Pipeline.py
new file mode 100644
index 0000000000000000000000000000000000000000..1b6eab1e70e5a44330ca73f1950a94ee8dc7391f
--- /dev/null
+++ b/third_party/cython/src/Cython/Compiler/Pipeline.py
@@ -0,0 +1,342 @@
+import itertools
+from time import time
+
+import Errors
+import DebugFlags
+import Options
+from Visitor import CythonTransform
+from Errors import CompileError, InternalError, AbortError
+import Naming
+
+#
+# Really small pipeline stages
+#
+def dumptree(t):
+ # For quick debugging in pipelines
+ print t.dump()
+ return t
+
+def abort_on_errors(node):
+ # Stop the pipeline if there are any errors.
+ if Errors.num_errors != 0:
+ raise AbortError("pipeline break")
+ return node
+
+def parse_stage_factory(context):
+ def parse(compsrc):
+ source_desc = compsrc.source_desc
+ full_module_name = compsrc.full_module_name
+ initial_pos = (source_desc, 1, 0)
+ saved_cimport_from_pyx, Options.cimport_from_pyx = Options.cimport_from_pyx, False
+ scope = context.find_module(full_module_name, pos = initial_pos, need_pxd = 0,
+ check_module_name = not Options.embed)
+ Options.cimport_from_pyx = saved_cimport_from_pyx
+ tree = context.parse(source_desc, scope, pxd = 0, full_module_name = full_module_name)
+ tree.compilation_source = compsrc
+ tree.scope = scope
+ tree.is_pxd = False
+ return tree
+ return parse
+
+def parse_pxd_stage_factory(context, scope, module_name):
+ def parse(source_desc):
+ tree = context.parse(source_desc, scope, pxd=True,
+ full_module_name=module_name)
+ tree.scope = scope
+ tree.is_pxd = True
+ return tree
+ return parse
+
+def generate_pyx_code_stage_factory(options, result):
+ def generate_pyx_code_stage(module_node):
+ module_node.process_implementation(options, result)
+ result.compilation_source = module_node.compilation_source
+ return result
+ return generate_pyx_code_stage
+
+def inject_pxd_code_stage_factory(context):
+ def inject_pxd_code_stage(module_node):
+ from textwrap import dedent
+ stats = module_node.body.stats
+ for name, (statlistnode, scope) in context.pxds.iteritems():
+ module_node.merge_in(statlistnode, scope)
+ return module_node
+ return inject_pxd_code_stage
+
+def use_utility_code_definitions(scope, target, seen=None):
+ if seen is None:
+ seen = set()
+
+ for entry in scope.entries.itervalues():
+ if entry in seen:
+ continue
+
+ seen.add(entry)
+ if entry.used and entry.utility_code_definition:
+ target.use_utility_code(entry.utility_code_definition)
+ for required_utility in entry.utility_code_definition.requires:
+ target.use_utility_code(required_utility)
+ elif entry.as_module:
+ use_utility_code_definitions(entry.as_module, target, seen)
+
+def inject_utility_code_stage_factory(context):
+ def inject_utility_code_stage(module_node):
+ use_utility_code_definitions(context.cython_scope, module_node.scope)
+ added = []
+ # Note: the list might be extended inside the loop (if some utility code
+ # pulls in other utility code, explicitly or implicitly)
+ for utilcode in module_node.scope.utility_code_list:
+ if utilcode in added: continue
+ added.append(utilcode)
+ if utilcode.requires:
+ for dep in utilcode.requires:
+ if not dep in added and not dep in module_node.scope.utility_code_list:
+ module_node.scope.utility_code_list.append(dep)
+ tree = utilcode.get_tree()
+ if tree:
+ module_node.merge_in(tree.body, tree.scope, merge_scope=True)
+ return module_node
+ return inject_utility_code_stage
+
+class UseUtilityCodeDefinitions(CythonTransform):
+ # Temporary hack to use any utility code in nodes' "utility_code_definitions".
+ # This should be moved to the code generation phase of the relevant nodes once
+ # it is safe to generate CythonUtilityCode at code generation time.
+ def __call__(self, node):
+ self.scope = node.scope
+ return super(UseUtilityCodeDefinitions, self).__call__(node)
+
+ def process_entry(self, entry):
+ if entry:
+ for utility_code in (entry.utility_code, entry.utility_code_definition):
+ if utility_code:
+ self.scope.use_utility_code(utility_code)
+
+ def visit_AttributeNode(self, node):
+ self.process_entry(node.entry)
+ return node
+
+ def visit_NameNode(self, node):
+ self.process_entry(node.entry)
+ self.process_entry(node.type_entry)
+ return node
+
+#
+# Pipeline factories
+#
+
+def create_pipeline(context, mode, exclude_classes=()):
+ assert mode in ('pyx', 'py', 'pxd')
+ from Visitor import PrintTree
+ from ParseTreeTransforms import WithTransform, NormalizeTree, PostParse, PxdPostParse
+ from ParseTreeTransforms import ForwardDeclareTypes, AnalyseDeclarationsTransform
+ from ParseTreeTransforms import AnalyseExpressionsTransform, FindInvalidUseOfFusedTypes
+ from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform
+ from ParseTreeTransforms import InterpretCompilerDirectives, TransformBuiltinMethods
+ from ParseTreeTransforms import ExpandInplaceOperators, ParallelRangeTransform
+ from ParseTreeTransforms import CalculateQualifiedNamesTransform
+ from TypeInference import MarkParallelAssignments, MarkOverflowingArithmetic
+ from ParseTreeTransforms import AdjustDefByDirectives, AlignFunctionDefinitions
+ from ParseTreeTransforms import RemoveUnreachableCode, GilCheck
+ from FlowControl import ControlFlowAnalysis
+ from AnalysedTreeTransforms import AutoTestDictTransform
+ from AutoDocTransforms import EmbedSignature
+ from Optimize import FlattenInListTransform, SwitchTransform, IterationTransform
+ from Optimize import EarlyReplaceBuiltinCalls, OptimizeBuiltinCalls
+ from Optimize import InlineDefNodeCalls
+ from Optimize import ConstantFolding, FinalOptimizePhase
+ from Optimize import DropRefcountingTransform
+ from Optimize import ConsolidateOverflowCheck
+ from Buffer import IntroduceBufferAuxiliaryVars
+ from ModuleNode import check_c_declarations, check_c_declarations_pxd
+
+
+ if mode == 'pxd':
+ _check_c_declarations = check_c_declarations_pxd
+ _specific_post_parse = PxdPostParse(context)
+ else:
+ _check_c_declarations = check_c_declarations
+ _specific_post_parse = None
+
+ if mode == 'py':
+ _align_function_definitions = AlignFunctionDefinitions(context)
+ else:
+ _align_function_definitions = None
+
+ # NOTE: This is the "common" parts of the pipeline, which is also
+ # code in pxd files. So it will be run multiple times in a
+ # compilation stage.
+ stages = [
+ NormalizeTree(context),
+ PostParse(context),
+ _specific_post_parse,
+ InterpretCompilerDirectives(context, context.compiler_directives),
+ ParallelRangeTransform(context),
+ AdjustDefByDirectives(context),
+ MarkClosureVisitor(context),
+ _align_function_definitions,
+ RemoveUnreachableCode(context),
+ ConstantFolding(),
+ FlattenInListTransform(),
+ WithTransform(context),
+ DecoratorTransform(context),
+ ForwardDeclareTypes(context),
+ AnalyseDeclarationsTransform(context),
+ AutoTestDictTransform(context),
+ EmbedSignature(context),
+ EarlyReplaceBuiltinCalls(context), ## Necessary?
+ TransformBuiltinMethods(context), ## Necessary?
+ MarkParallelAssignments(context),
+ ControlFlowAnalysis(context),
+ RemoveUnreachableCode(context),
+ # MarkParallelAssignments(context),
+ MarkOverflowingArithmetic(context),
+ IntroduceBufferAuxiliaryVars(context),
+ _check_c_declarations,
+ InlineDefNodeCalls(context),
+ AnalyseExpressionsTransform(context),
+ FindInvalidUseOfFusedTypes(context),
+ ExpandInplaceOperators(context),
+ OptimizeBuiltinCalls(context), ## Necessary?
+ CreateClosureClasses(context), ## After all lookups and type inference
+ CalculateQualifiedNamesTransform(context),
+ ConsolidateOverflowCheck(context),
+ IterationTransform(context),
+ SwitchTransform(),
+ DropRefcountingTransform(),
+ FinalOptimizePhase(context),
+ GilCheck(),
+ UseUtilityCodeDefinitions(context),
+ ]
+ filtered_stages = []
+ for s in stages:
+ if s.__class__ not in exclude_classes:
+ filtered_stages.append(s)
+ return filtered_stages
+
+def create_pyx_pipeline(context, options, result, py=False, exclude_classes=()):
+ if py:
+ mode = 'py'
+ else:
+ mode = 'pyx'
+ test_support = []
+ if options.evaluate_tree_assertions:
+ from Cython.TestUtils import TreeAssertVisitor
+ test_support.append(TreeAssertVisitor())
+
+ if options.gdb_debug:
+ from Cython.Debugger import DebugWriter # requires Py2.5+
+ from ParseTreeTransforms import DebugTransform
+ context.gdb_debug_outputwriter = DebugWriter.CythonDebugWriter(
+ options.output_dir)
+ debug_transform = [DebugTransform(context, options, result)]
+ else:
+ debug_transform = []
+
+ return list(itertools.chain(
+ [parse_stage_factory(context)],
+ create_pipeline(context, mode, exclude_classes=exclude_classes),
+ test_support,
+ [inject_pxd_code_stage_factory(context),
+ inject_utility_code_stage_factory(context),
+ abort_on_errors],
+ debug_transform,
+ [generate_pyx_code_stage_factory(options, result)]))
+
+def create_pxd_pipeline(context, scope, module_name):
+ from CodeGeneration import ExtractPxdCode
+
+ # The pxd pipeline ends up with a CCodeWriter containing the
+ # code of the pxd, as well as a pxd scope.
+ return [
+ parse_pxd_stage_factory(context, scope, module_name)
+ ] + create_pipeline(context, 'pxd') + [
+ ExtractPxdCode()
+ ]
+
+def create_py_pipeline(context, options, result):
+ return create_pyx_pipeline(context, options, result, py=True)
+
+def create_pyx_as_pxd_pipeline(context, result):
+ from ParseTreeTransforms import AlignFunctionDefinitions, \
+ MarkClosureVisitor, WithTransform, AnalyseDeclarationsTransform
+ from Optimize import ConstantFolding, FlattenInListTransform
+ from Nodes import StatListNode
+ pipeline = []
+ pyx_pipeline = create_pyx_pipeline(context, context.options, result,
+ exclude_classes=[
+ AlignFunctionDefinitions,
+ MarkClosureVisitor,
+ ConstantFolding,
+ FlattenInListTransform,
+ WithTransform
+ ])
+ for stage in pyx_pipeline:
+ pipeline.append(stage)
+ if isinstance(stage, AnalyseDeclarationsTransform):
+ # This is the last stage we need.
+ break
+ def fake_pxd(root):
+ for entry in root.scope.entries.values():
+ if not entry.in_cinclude:
+ entry.defined_in_pxd = 1
+ if entry.name == entry.cname and entry.visibility != 'extern':
+ # Always mangle non-extern cimported entries.
+ entry.cname = entry.scope.mangle(Naming.func_prefix, entry.name)
+ return StatListNode(root.pos, stats=[]), root.scope
+ pipeline.append(fake_pxd)
+ return pipeline
+
+def insert_into_pipeline(pipeline, transform, before=None, after=None):
+ """
+ Insert a new transform into the pipeline after or before an instance of
+ the given class. e.g.
+
+ pipeline = insert_into_pipeline(pipeline, transform,
+ after=AnalyseDeclarationsTransform)
+ """
+ assert before or after
+
+ cls = before or after
+ for i, t in enumerate(pipeline):
+ if isinstance(t, cls):
+ break
+
+ if after:
+ i += 1
+
+ return pipeline[:i] + [transform] + pipeline[i:]
+
+#
+# Running a pipeline
+#
+
+def run_pipeline(pipeline, source, printtree=True):
+ from Cython.Compiler.Visitor import PrintTree
+
+ error = None
+ data = source
+ try:
+ try:
+ for phase in pipeline:
+ if phase is not None:
+ if DebugFlags.debug_verbose_pipeline:
+ t = time()
+ print "Entering pipeline phase %r" % phase
+ if not printtree and isinstance(phase, PrintTree):
+ continue
+ data = phase(data)
+ if DebugFlags.debug_verbose_pipeline:
+ print " %.3f seconds" % (time() - t)
+ except CompileError, err:
+ # err is set
+ Errors.report_error(err)
+ error = err
+ except InternalError, err:
+ # Only raise if there was not an earlier error
+ if Errors.num_errors == 0:
+ raise
+ error = err
+ except AbortError, err:
+ error = err
+ return (error, data)
« no previous file with comments | « third_party/cython/src/Cython/Compiler/Parsing.py ('k') | third_party/cython/src/Cython/Compiler/PyrexTypes.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698