Пример #1
0
    def __init__(self, module, data_filename):
        PythonContextBase.__init__(self)

        TempMixin.__init__(self)
        CodeObjectsMixin.__init__(self)
        FrameDeclarationsMixin.__init__(self)
        ReturnReleaseModeMixin.__init__(self)

        # TODO: For outlines bodies.
        ReturnValueNameMixin.__init__(self)

        self.module = module
        self.name = module.getFullName()
        self.code_name = module.getCodeName()

        self.declaration_codes = {}
        self.helper_codes = {}

        self.frame_handle = None

        self.variable_storage = VariableStorage(heap_name=None)

        self.function_table_entries = []

        self.constant_accessor = ConstantAccessor(
            top_level_name="mod_consts", data_filename=data_filename
        )
def compileTree():
    source_dir = OutputDirectories.getSourceDirectoryPath()

    general.info("Completed Python level compilation and optimization.")

    if not Options.shallOnlyExecCCompilerCall():
        general.info("Generating source code for C backend compiler.")

        if Options.isShowProgress() or Options.isShowMemory():
            general.info(
                "Total memory usage before generating C code: {memory}:".
                format(
                    memory=MemoryUsage.getHumanReadableProcessMemoryUsage()))
        # Now build the target language code for the whole tree.
        makeSourceDirectory()

        bytecode_accessor = ConstantAccessor(data_filename="__bytecode.const",
                                             top_level_name="bytecode_data")

        # This should take all bytecode values, even ones needed for frozen or
        # not produce anything.
        loader_code = LoaderCodes.getMetapathLoaderBodyCode(bytecode_accessor)

        writeSourceCode(filename=os.path.join(source_dir, "__loader.c"),
                        source_code=loader_code)

    else:
        source_dir = OutputDirectories.getSourceDirectoryPath()

        if not os.path.isfile(os.path.join(source_dir, "__helpers.h")):
            general.sysexit("Error, no previous build directory exists.")

    if Options.isShowProgress() or Options.isShowMemory():
        general.info(
            "Total memory usage before running scons: {memory}:".format(
                memory=MemoryUsage.getHumanReadableProcessMemoryUsage()))

    if Options.isShowMemory():
        InstanceCounters.printStats()

    if Options.is_debug:
        Reports.doMissingOptimizationReport()

    if Options.shallNotDoExecCCompilerCall():
        return True, {}

    general.info(
        "Running data composer tool for optimal constant value handling.")

    # TODO: On Windows, we could run this in parallel to Scons, on Linux we need it
    # for linking.
    runDataComposer(source_dir)

    general.info("Running C level backend compilation via Scons.")

    # Run the Scons to build things.
    result, options = runSconsBackend(quiet=not Options.isShowScons())

    return result, options
Пример #3
0
def getConstantsDefinitionCode():
    """Create the code code "__constants.c" and "__constants.h" files.

    This needs to create code to make all global constants (used in more
    than one module) and create them.

    """
    constant_accessor = ConstantAccessor(data_filename="__constants.const",
                                         top_level_name="global_constants")

    lines = []

    for constant_value in getConstantDefaultPopulation():
        identifier = constant_accessor.getConstantCode(constant_value)

        assert "[" in identifier, (identifier, constant_value)

        lines.append("// %s" % repr(constant_value))
        lines.append("#define const_%s %s" %
                     (namifyConstant(constant_value), identifier))

    sys_executable = None

    if not Options.shallMakeModule():
        if Options.isStandaloneMode():
            # The directory is added back at run time.
            sys_executable = constant_accessor.getConstantCode(
                os.path.basename(sys.executable))
        else:
            sys_executable = constant_accessor.getConstantCode(sys.executable)

    sys_prefix = None
    sys_base_prefix = None
    sys_exec_prefix = None
    sys_base_exec_prefix = None

    # TODO: This part is needed for main program only, so do it there?
    if not Options.shallMakeModule() and not Options.isStandaloneMode():
        sys_prefix = constant_accessor.getConstantCode(sys.prefix)
        sys_exec_prefix = constant_accessor.getConstantCode(sys.exec_prefix)

        if python_version >= 300:
            sys_base_prefix = constant_accessor.getConstantCode(
                sys.base_prefix)
            sys_base_exec_prefix = constant_accessor.getConstantCode(
                sys.base_exec_prefix)

    lines.insert(
        0,
        "extern PyObject *global_constants[%d];" %
        constant_accessor.getConstantsCount(),
    )

    header = template_header_guard % {
        "header_guard_name": "__NUITKA_GLOBAL_CONSTANTS_H__",
        "header_body": "\n".join(lines),
    }

    major, minor, micro = getNuitkaVersion().split(".")[:3]

    if "rc" in micro:
        micro = micro[:micro.find("rc")]
        level = "candidate"
    else:
        level = "release"

    body = template_constants_reading % {
        "global_constants_count": constant_accessor.getConstantsCount(),
        "sys_executable": sys_executable,
        "sys_prefix": sys_prefix,
        "sys_base_prefix": sys_base_prefix,
        "sys_exec_prefix": sys_exec_prefix,
        "sys_base_exec_prefix": sys_base_exec_prefix,
        "nuitka_version_major": major,
        "nuitka_version_minor": minor,
        "nuitka_version_micro": micro,
        "nuitka_version_level": level,
    }

    return header, body
Пример #4
0
class PythonModuleContext(
    TempMixin,
    CodeObjectsMixin,
    FrameDeclarationsMixin,
    ReturnReleaseModeMixin,
    ReturnValueNameMixin,
    PythonContextBase,
):
    # Plenty of attributes, because it's storing so many different things.
    # pylint: disable=too-many-instance-attributes

    def __init__(self, module, data_filename):
        PythonContextBase.__init__(self)

        TempMixin.__init__(self)
        CodeObjectsMixin.__init__(self)
        FrameDeclarationsMixin.__init__(self)
        ReturnReleaseModeMixin.__init__(self)

        # TODO: For outlines bodies.
        ReturnValueNameMixin.__init__(self)

        self.module = module
        self.name = module.getFullName()
        self.code_name = module.getCodeName()

        self.declaration_codes = {}
        self.helper_codes = {}

        self.frame_handle = None

        self.variable_storage = VariableStorage(heap_name=None)

        self.function_table_entries = []

        self.constant_accessor = ConstantAccessor(
            top_level_name="mod_consts", data_filename=data_filename
        )

    def __repr__(self):
        return "<PythonModuleContext instance for module %s>" % self.name

    def getOwner(self):
        return self.module

    def getEntryPoint(self):
        return self.module

    def isCompiledPythonModule(self):
        return True

    def getName(self):
        return self.name

    def mayRaiseException(self):
        body = self.module.subnode_body

        return body is not None and body.mayRaiseException(BaseException)

    getModuleName = getName

    def getModuleCodeName(self):
        return self.code_name

    def setFrameGuardMode(self, guard_mode):
        assert guard_mode == "once"

    def addHelperCode(self, key, code):
        assert key not in self.helper_codes, key

        self.helper_codes[key] = code

    def hasHelperCode(self, key):
        return key in self.helper_codes

    def getHelperCodes(self):
        return self.helper_codes

    def addDeclaration(self, key, code):
        assert key not in self.declaration_codes

        self.declaration_codes[key] = code

    def getDeclarations(self):
        return self.declaration_codes

    def mayRecurse(self):
        return False

    def getConstantCode(self, constant, deep_check=False):
        if deep_check and Options.is_debug:
            assert not isMutable(constant)

        return self.constant_accessor.getConstantCode(constant)

    def getConstantsCount(self):
        return self.constant_accessor.getConstantsCount()

    def addFunctionCreationInfo(self, creation_info):
        self.function_table_entries.append(creation_info)

    def getFunctionCreationInfos(self):
        result = self.function_table_entries

        # Release the memory once possible.
        del self.function_table_entries
        return result