Beispiel #1
0
bool AndroidExporter::ExportMainFile(gd::Project& project,
                                     gd::String outputDir) {
  gd::String layoutFunctionDeclarations;
  gd::String functionAssignmentCode;

  for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) {
    auto layout = project.GetLayout(i);
    gd::String layoutFunctionName =
        "GDSceneEvents" +
        gd::SceneNameMangler::GetMangledSceneName(layout.GetName());

    gd::EventsCodeGenerator codeGenerator(project, layout, CppPlatform::Get());
    layoutFunctionDeclarations += "extern \"C\" int  " + layoutFunctionName +
                                  "(RuntimeContext * runtimeContext);\n";
    functionAssignmentCode += "\t\tif (scene.GetName() == \"" +
                              codeGenerator.ConvertToString(layout.GetName()) +
                              "\") function = &" + layoutFunctionName + ";\n";
  }

  gd::String mainFile = fs.ReadFile(GetAndroidProjectPath() + "/jni/main.cpp")
                            .FindAndReplace("/* GDCPP_EVENTS_DECLARATIONS */",
                                            layoutFunctionDeclarations)
                            .FindAndReplace("/* GDCPP_EVENTS_ASSIGNMENTS */",
                                            functionAssignmentCode);

  return fs.WriteToFile(outputDir + "/jni/main.cpp", mainFile);
}
Beispiel #2
0
/*
*****************************************************************************************************************
*	startGeneration:
*		root 		: The ASTNode* generated after creating AST.
*	This function initializes the link list of three address code which is to be generated.
*	Calls codeGenerator function which does rest of the job.
*****************************************************************************************************************
*/
void startGeneration(ASTNode* root){
	CODE_HEAD = NULL;
	CODE_TAIL = NULL;
	FunctionNode* funInfo = (FunctionNode*)malloc(sizeof(FunctionNode));
	FunctionNode* freeFunInfo = funInfo;
	funInfo->funTok = root->child->token;
	funInfo = (FunctionNode*)get(FUNCTION_TABLE.hashTable,funInfo);
	Label* currLabel = (Label*)malloc(sizeof(Label));
	currLabel->labelType = 1;
	currLabel->labelNum = 0;
	codeGenerator(root->child,funInfo,currLabel,0);	
}
Beispiel #3
0
		bool generateOutput(const string& fileContents, const string& outputBitCodeName) {
			// Parse the source file
			//cout << "Parsing..." << endl;
			base_expr_node rootAst;
			if (!parse(fileContents, rootAst)) {
				cerr << "Failed to parse source file!" << endl;
				return false;
			}

			// Generate the code
			//cout << "Generating code..." << endl;
			LLVMContext &context = getGlobalContext();
			unique_ptr<Module> module(new Module("", context));
			IRBuilder<> builder(getGlobalContext());

			ast_codegen codeGenerator(module.get(), builder);

			// Generate code for each expression at the root level
			const base_expr* expr = boost::get<base_expr>(&rootAst);
			for (auto& itr : expr->children) {
				boost::apply_visitor(codeGenerator, itr);
			}

			// Perform an LLVM verify as a sanity check
			string errorInfo;
			raw_string_ostream errorOut(errorInfo);

			if (verifyModule(*module, &errorOut)) {
				cerr << "Failed to generate LLVM IR: " << errorInfo << endl;

				module->print(errorOut, nullptr);
				cerr << "Module:" << endl << errorInfo << endl;
				return false;
			}

			// Dump the LLVM IR to a file
			llvm::raw_fd_ostream outStream(outputBitCodeName.c_str(), errorInfo, llvm::sys::fs::F_None);
			llvm::WriteBitcodeToFile(module.get(), outStream);

			return true;
		}
Beispiel #4
0
/*
*****************************************************************************************************************
*	codeGenerator:
*		child 		: The ASTNode for which the code has to be generated.
*		funInfo 	: This has the FunctionNode(see astDef.h for details) for the function 
*				  	  which has the 'child'.
*		currLabel	: Possible label which can be assigned to the current instruction.
*		parentLabel : The label of the parent node in AST.
*	This function simply does the post order traversal of a function and generates code for that function.
*	In our case it works only for the main function.
*****************************************************************************************************************
*/
void codeGenerator(ASTNode* child,FunctionNode* funInfo,Label* currLabel, int parentLabel){
	if(child==NULL){
		return;
	}
	int tempCount = funInfo->width;
	int tempLabel = currLabel->labelNum;
	InstructionList* funLabel = NULL;
	ASTNode* ifChild = NULL;
	int ifFlag=0;
	TokenName tokenName = child->token->tokenName;
	switch(tokenName){
		case TK_MAIN: funLabel = createLabel(1,0);
					  strcpy(funLabel->label,"main");
					  generate(funLabel);
					  createCallStack(child);
					  break;
		case TK_ASSIGNOP:	generateArithmeticExpression(child,funInfo->funTok,&tempCount);
							break;
		case TK_IF: currLabel->labelNum += 2;
					generateBooleanExpression(child->child,funInfo->funTok,addLabel(1,tempLabel),addLabel(0,tempLabel),currLabel,&tempCount);
					generate(createLabel(1,tempLabel));
					break;
		case TK_ELSE: generate(createInstruction(JMP,-1,-1,parentLabel+1,1,0));
					  generate(createLabel(0,parentLabel));
					  break;
		case TK_READ: generateScanf(child->child,funInfo);
					  break;
		case TK_WRITE: generatePrintf(child->child,funInfo);
						break;
		case TK_WHILE: generate(createLabel(1,currLabel->labelNum));
					   currLabel->labelNum += 2;
					   generateBooleanExpression(child->child,funInfo->funTok,addLabel(1,tempLabel+1),addLabel(0,tempLabel),currLabel,&tempCount);
					   generate(createLabel(1,tempLabel+1));
					   break;
	}
	if(tokenName==TK_IF)
		codeGenerator(child->child,funInfo,currLabel, tempLabel);
	else
		codeGenerator(child->child,funInfo,currLabel, parentLabel);
	switch(tokenName){
		case TK_MAIN:  generate(createInstruction(ADD,RSP,IMM,0,0,funInfo->width+funInfo->tempCount));
						generate(createInstruction(RET,-1,-1,-1,-1,-1));
						break;
		case TK_WHILE:  generate(createInstruction(JMP,-1,-1,tempLabel,1,0));
						generate(createLabel(0,tempLabel));
					  break;	
		case TK_IF:		generate(createLabel(1,tempLabel+1));
						ifChild = child->child;
						while(ifChild!=NULL){
							if(ifChild->token->tokenName==TK_ELSE){
								ifFlag = 1;
								break;
							}
							ifChild = ifChild->next;
						}
						if(!ifFlag)
						generate(createLabel(0,tempLabel));
						break;
	}
	codeGenerator(child->next,funInfo,currLabel, parentLabel);	
}
Beispiel #5
0
uint8_t *
compileMethodFromDetails(
      OMR_VMThread *omrVMThread,
      TR::IlGeneratorMethodDetails & details,
      TR_Hotness hotness,
      int32_t &rc)
   {
   uint64_t translationStartTime = TR::Compiler->vm.getUSecClock();
   OMR::FrontEnd &fe = OMR::FrontEnd::singleton();
   auto jitConfig = fe.jitConfig();
   TR::RawAllocator rawAllocator;
   TR::SystemSegmentProvider defaultSegmentProvider(1 << 16, rawAllocator);
   TR::DebugSegmentProvider debugSegmentProvider(1 << 16, rawAllocator);
   TR::SegmentAllocator &scratchSegmentProvider =
      TR::Options::getCmdLineOptions()->getOption(TR_EnableScratchMemoryDebugging) ?
         static_cast<TR::SegmentAllocator &>(debugSegmentProvider) :
         static_cast<TR::SegmentAllocator &>(defaultSegmentProvider);
   TR::Region dispatchRegion(scratchSegmentProvider, rawAllocator);
   TR_Memory trMemory(*fe.persistentMemory(), dispatchRegion);
   TR_ResolvedMethod & compilee = *((TR_ResolvedMethod *)details.getMethod());

   TR::CompileIlGenRequest request(details);

   // initialize return code before compilation starts
   rc = COMPILATION_REQUESTED;

   uint8_t *startPC = 0;

   TR_FilterBST *filterInfo = 0;
   TR_OptimizationPlan *plan = 0;
   if (!methodCanBeCompiled(&fe, compilee, filterInfo, &trMemory))
      {
      if (TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerboseCompileExclude))
         {
         TR_VerboseLog::write("<JIT: %s cannot be translated>\n",
                              compilee.signature(&trMemory));
         }
      return 0;
      }

   if (0 == (plan = TR_OptimizationPlan::alloc(hotness, false, false)))
      {
      // FIXME: maybe it would be better to allocate the plan on the stack
      // so that we don't have to deal with OOM ugliness below
      if (TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerboseCompileExclude))
         {
         TR_VerboseLog::write("<JIT: %s out-of-memory allocating optimization plan>\n",
                              compilee.signature(&trMemory));
         }
      return 0;
      }

   int32_t optionSetIndex = filterInfo ? filterInfo->getOptionSet() : 0;
   int32_t lineNumber = filterInfo ? filterInfo->getLineNumber() : 0;
   TR::Options options(
         &trMemory,
         optionSetIndex,
         lineNumber,
         &compilee,
         0,
         plan,
         false);

   // FIXME: once we can do recompilation , we need to pass in the old start PC  -----------------------^

   // FIXME: what happens if we can't allocate memory at the new above?
   // FIXME: perhaps use stack memory instead

   TR_ASSERT(TR::comp() == NULL, "there seems to be a current TLS TR::Compilation object %p for this thread. At this point there should be no current TR::Compilation object", TR::comp());
   TR::Compilation compiler(0, omrVMThread, &fe, &compilee, request, options, dispatchRegion, &trMemory, plan);
   TR_ASSERT(TR::comp() == &compiler, "the TLS TR::Compilation object %p for this thread does not match the one %p just created.", TR::comp(), &compiler);

   try
      {
      //fprintf(stderr,"loading JIT debug\n");
      if (TR::Options::requiresDebugObject()
          || options.getLogFileName()
          || options.enableDebugCounters())
         {
         compiler.setDebug(createDebugObject(&compiler));
         }

      compiler.setIlVerifier(details.getIlVerifier());

      if (TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerboseCompileStart))
         {
         const char *signature = compilee.signature(&trMemory);
         TR_VerboseLog::writeLineLocked(TR_Vlog_COMPSTART,"compiling %s",
                                                          signature);
         }

      if (compiler.getOutFile() != NULL && compiler.getOption(TR_TraceAll))
         {
         const char *signature = compilee.signature(&trMemory);
         traceMsg((&compiler), "<compile hotness=\"%s\" method=\"%s\">\n",
                               compiler.getHotnessName(compiler.getMethodHotness()),
                               signature);
         }

      compiler.getJittedMethodSymbol()->setLinkage(TR_System);

      // --------------------------------------------------------------------
      // Compile the method
      //
      rc = compiler.compile();

      if (rc == COMPILATION_SUCCEEDED) // success!
         {

         // not ready yet...
         //OMR::MethodMetaDataPOD *metaData = fe.createMethodMetaData(&compiler);

         startPC = compiler.cg()->getCodeStart();
         uint64_t translationTime = TR::Compiler->vm.getUSecClock() - translationStartTime;

         if (TR::Options::isAnyVerboseOptionSet(TR_VerboseCompileEnd, TR_VerbosePerformance))
            {
            const char *signature = compilee.signature(&trMemory);
            TR_VerboseLog::vlogAcquire();
            TR_VerboseLog::writeLine(TR_Vlog_COMP,"(%s) %s @ " POINTER_PRINTF_FORMAT "-" POINTER_PRINTF_FORMAT,
                                           compiler.getHotnessName(compiler.getMethodHotness()),
                                           signature,
                                           startPC,
                                           compiler.cg()->getCodeEnd());

            if (TR::Options::getVerboseOption(TR_VerbosePerformance))
               {
               TR_VerboseLog::write(
                  " time=%llu mem=%lluKB",
                  translationTime,
                  static_cast<unsigned long long>(scratchSegmentProvider.bytesAllocated()) / 1024
                  );
               }

            TR_VerboseLog::vlogRelease();
            trfflush(jitConfig->options.vLogFile);
            }

         if (
               TR::Options::getCmdLineOptions()->getOption(TR_PerfTool) 
            || TR::Options::getCmdLineOptions()->getOption(TR_EmitExecutableELFFile)
            || TR::Options::getCmdLineOptions()->getOption(TR_EmitRelocatableELFFile)
            )
            {
            TR::CodeCacheManager &codeCacheManager(fe.codeCacheManager());
            TR::CodeGenerator &codeGenerator(*compiler.cg());
            codeCacheManager.registerCompiledMethod(compiler.externalName(), startPC, codeGenerator.getCodeLength());
            if (TR::Options::getCmdLineOptions()->getOption(TR_EmitRelocatableELFFile))
               {
               auto &relocations = codeGenerator.getStaticRelocations();
               for (auto it = relocations.begin(); it != relocations.end(); ++it)
                  {
                  codeCacheManager.registerStaticRelocation(*it);
                  }
               }
            if (TR::Options::getCmdLineOptions()->getOption(TR_PerfTool))
               {
               generatePerfToolEntry(startPC, codeGenerator.getCodeEnd(), compiler.signature(), compiler.getHotnessName(compiler.getMethodHotness()));
               }
            }

         if (compiler.getOutFile() != NULL && compiler.getOption(TR_TraceAll))
            traceMsg((&compiler), "<result success=\"true\" startPC=\"%#p\" time=\"%lld.%lldms\"/>\n",
                                  startPC,
                                  translationTime/1000,
                                  translationTime%1000);
         }
      else /* of rc == COMPILATION_SUCCEEDED */
         {
         TR_ASSERT(false, "compiler error code %d returned\n", rc);
         }

      if (compiler.getOption(TR_BreakAfterCompile))
         {
         TR::Compiler->debug.breakPoint();
         }

      }
   catch (const TR::ILValidationFailure &exception)
      {
      rc = COMPILATION_IL_VALIDATION_FAILURE;
#if defined(J9ZOS390)
      // Compiling with -Wc,lp64 results in a crash on z/OS when trying
      // to call the what() virtual method of the exception.
      printCompFailureInfo(jitConfig, &compiler, "");
#else
      printCompFailureInfo(jitConfig, &compiler, exception.what());
#endif
      } 
   catch (const std::exception &exception)
      {
      // failed! :-(

#if defined(J9ZOS390)
      // Compiling with -Wc,lp64 results in a crash on z/OS when trying
      // to call the what() virtual method of the exception.
      printCompFailureInfo(jitConfig, &compiler, "");
#else
      printCompFailureInfo(jitConfig, &compiler, exception.what());
#endif
      }

   // A better place to do this would have been the destructor for
   // TR::Compilation. We'll need exceptions working instead of setjmp
   // before we can get working, and we need to make sure the other
   // frontends are properly calling the destructor
   TR::CodeCacheManager::instance()->unreserveCodeCache(compiler.getCurrentCodeCache());

   TR_OptimizationPlan::freeOptimizationPlan(plan);


   return startPC;
   }