Beispiel #1
0
def getConstantInitCodes(module_context):
    decls = []
    inits = Emission.SourceCodeCollector()
    checks = Emission.SourceCodeCollector()

    sorted_constants = sorted(
        module_context.getConstants(),
        key = lambda k: (len(k[0]), k[0])
    )

    global_context = module_context.global_context

    for constant_identifier in sorted_constants:
        if not constant_identifier.startswith("const_"):
            continue

        if global_context.getConstantUseCount(constant_identifier) == 1:
            qualifier = "static"

            constant_value = global_context.constants[constant_identifier]

            _addConstantInitCode(
                emit                = inits,
                check               = checks,
                constant_type       = type(constant_value),
                constant_value      = constant_value,
                constant_identifier = constant_identifier,
                module_level        = True,
                context             = module_context
            )
        else:
            qualifier = "extern"

        decls.append(
            "%s PyObject *%s;" % (
                qualifier,
                constant_identifier
            )
        )

        if Options.isDebug():
            decls.append(
                "%s Py_hash_t hash_%s;" % (
                    qualifier,
                    constant_identifier
                )
            )

    return decls, inits.codes, checks.codes
Beispiel #2
0
def getModuleValues(
    context,
    module_name,
    module_identifier,
    function_decl_codes,
    function_body_codes,
    outline_variables,
    temp_variables,
    is_main_module,
    is_internal_module,
    is_package,
    is_top,
):
    # For the module code, lots of arguments and attributes come together.
    # pylint: disable=too-many-locals

    # Temporary variable initializations
    # TODO: Move that to a place outside of functions.
    from .FunctionCodes import (
        setupFunctionLocalVariables,
        finalizeFunctionLocalVariables,
    )

    setupFunctionLocalVariables(
        context=context,
        parameters=None,
        closure_variables=(),
        user_variables=outline_variables,
        temp_variables=temp_variables,
    )

    module_codes = Emission.SourceCodeCollector()

    module_body = context.getOwner().getBody()

    generateStatementSequenceCode(
        statement_sequence=module_body,
        emit=module_codes,
        allow_none=True,
        context=context,
    )

    for _identifier, code in sorted(iterItems(context.getHelperCodes())):
        function_body_codes.append(code)

    for _identifier, code in sorted(iterItems(context.getDeclarations())):
        function_decl_codes.append(code)

    function_body_codes = "\n\n".join(function_body_codes)
    function_decl_codes = "\n\n".join(function_decl_codes)

    _cleanup = finalizeFunctionLocalVariables(context)

    # TODO: Seems like a bug, classes could produce those.
    # assert not _cleanup, _cleanup

    local_var_inits = context.variable_storage.makeCFunctionLevelDeclarations()

    if module_body is not None and module_body.mayRaiseException(
            BaseException):
        module_exit = template_module_exception_exit
    else:
        module_exit = template_module_noexception_exit

    module_body_template_values = {
        "module_name": module_name,
        "module_name_obj": context.getConstantCode(constant=module_name),
        "is_main_module": 1 if is_main_module else 0,
        "is_package": 1 if is_package else 0,
        "is_top": 1 if is_top else 0,
        "module_identifier": module_identifier,
        "module_functions_decl": function_decl_codes,
        "module_functions_code": function_body_codes,
        "temps_decl": indented(local_var_inits),
        "module_code": indented(module_codes.codes),
        "module_exit": module_exit,
        "module_code_objects_decl": indented(getCodeObjectsDeclCode(context),
                                             0),
        "module_code_objects_init": indented(getCodeObjectsInitCode(context),
                                             1),
    }

    allocateNestedConstants(context)

    # Force internal module to not need constants init, by making all its
    # constants be shared.
    if is_internal_module:
        for constant in context.getConstants():
            context.global_context.countConstantUse(constant)

    return module_body_template_values
Beispiel #3
0
def getModuleCode(module, function_decl_codes, function_body_codes, context):

    # For the module code, lots of arguments and attributes come together.
    # pylint: disable=too-many-locals

    # Temporary variable initializations
    # TODO: Move that to a place outside of functions.
    from .FunctionCodes import (
        finalizeFunctionLocalVariables,
        setupFunctionLocalVariables,
    )

    setupFunctionLocalVariables(
        context=context,
        parameters=None,
        closure_variables=(),
        user_variables=module.getOutlineLocalVariables(),
        temp_variables=module.getTempVariables(),
    )

    module_codes = Emission.SourceCodeCollector()

    module = context.getOwner()
    module_body = module.getBody()

    generateStatementSequenceCode(
        statement_sequence=module_body,
        emit=module_codes,
        allow_none=True,
        context=context,
    )

    for _identifier, code in sorted(iterItems(context.getHelperCodes())):
        function_body_codes.append(code)

    for _identifier, code in sorted(iterItems(context.getDeclarations())):
        function_decl_codes.append(code)

    function_body_codes = "\n\n".join(function_body_codes)
    function_decl_codes = "\n\n".join(function_decl_codes)

    _cleanup = finalizeFunctionLocalVariables(context)

    # TODO: Seems like a bug, classes could produce those.
    # assert not _cleanup, _cleanup

    local_var_inits = context.variable_storage.makeCFunctionLevelDeclarations()

    if module_body is not None and module_body.mayRaiseException(
            BaseException):
        module_exit = template_module_exception_exit
    else:
        module_exit = template_module_noexception_exit

    function_table_entries_decl = []
    for func_impl_identifier in context.getFunctionCreationInfos():
        function_table_entries_decl.append("%s," % func_impl_identifier)

    module_name = module.getFullName()

    is_package = module.isCompiledPythonPackage()
    is_top = module.isTopModule()

    module_identifier = module.getCodeName()

    template = template_global_copyright + template_module_body_template

    if is_top == 1 and Options.shallMakeModule():
        template += template_module_external_entry_point

    module_code_objects_decl = getCodeObjectsDeclCode(context)
    module_code_objects_init = getCodeObjectsInitCode(context)

    return template % {
        "module_name":
        module_name,
        "version":
        getNuitkaVersion(),
        "year":
        getNuitkaVersionYear(),
        "is_main_module":
        1 if module.isMainModule() else 0,
        "is_dunder_main":
        1 if module_name == "__main__" and os.path.basename(
            module.getCompileTimeFilename()) == "__main__.py" else 0,
        "is_package":
        1 if is_package else 0,
        "module_identifier":
        module_identifier,
        "module_functions_decl":
        function_decl_codes,
        "module_functions_code":
        function_body_codes,
        "module_function_table_entries":
        indented(function_table_entries_decl),
        "temps_decl":
        indented(local_var_inits),
        "module_code":
        indented(module_codes.codes),
        "module_exit":
        module_exit,
        "module_code_objects_decl":
        indented(module_code_objects_decl, 0),
        "module_code_objects_init":
        indented(module_code_objects_init, 1),
        "constants_count":
        context.getConstantsCount(),
    }