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
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
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(), }