예제 #1
0
파일: backend.cpp 프로젝트: Geod24/dnet
// Generate code that initializes the elements of an array.
// Expects an array ref on the top of the stack.
dt_t* BackEnd::toDt(ArrayInitializer& init)
{
    ModuleEmitter& modScope = getModuleScope(init.loc);
    IRState* irstate = modScope.getCurrentIRState();
    if (!irstate)
    {
        fatalError(init.loc, "null IR state");
    }
    irstate->getBlock();
    VarDeclaration* varDecl = irstate->hasVarDecl();
    if (!varDecl)
    {
        BackEnd::fatalError(init.loc, "initializer expects var decl");
    }
    TYPE& type = toILType(init.loc, varDecl->type);
    ArrayType* aType = type.isArrayType();
    if (!aType)
    {
        BackEnd::fatalError(init.loc, "initializer expects array type");
    }
    aType->init(*irstate, *varDecl, init.dim);
    block& blk = irstate->getBlock();

    IRState temp(blk);
    ArrayAdapter<Initializer*> value(init.value);
    ArrayAdapter<Expression*> index(init.index);
    //
    // and here's where the elements are initialized:
    //
    for (size_t i = 0; i != init.dim; ++i)
    {
        if (i >= value.size() || i >= index.size())
        {
            assert(false);
            break;
        }
        if (i + 1 != init.dim)
        {
            // For each element duplicate the reference to the array
            // on the top of the stack, so that one is left on the stack for
            // the next element to use -- except when reaching the last element
            Instruction::create(blk, IL_dup);
        }
    #if 0
        //todo:revisit, indices may be null, what are they useful for anyway?
        DEREF(index[i]).toElem(irstate);
    #else
        Const<int>::create(*TYPE::Int32, i, blk, init.loc);
    #endif
        auto_ptr<dt_t>(DEREF(value[i]).toDt());
        ArrayElemAccess::store(blk, aType->elemTYPE());
    }
    return NULL;
}
예제 #2
0
파일: s2ir.c 프로젝트: Faianca/dmd
 void visit(DefaultStatement *s)
 {
     Blockx *blx = irs->blx;
     block *bcase = blx->curblock;
     block *bdefault = irs->getDefaultBlock();
     block_next(blx,BCgoto,bdefault);
     bcase->appendSucc(blx->curblock);
     if (blx->tryblock != irs->getSwitchBlock()->Btry)
         s->error("default cannot be in different try block level from switch");
     incUsage(irs, s->loc);
     if (s->statement)
         Statement_toIR(s->statement, irs);
 }
예제 #3
0
파일: modemit.cpp 프로젝트: Geod24/dnet
void ModuleEmitter::createVar(VarDeclaration& decl)
{
    //IF_DEBUG(clog << __FUNCSIG__ << ": "<< decl.toChars() << endl);
    // do not expect the decl to have a backend symbol associated with it
    assert(decl.csym == NULL);

    IRState* irState = getCurrentIRState();
    // variable is at module scope, or function-scope static?
    if ((irState == irState_) ||
        (irState->hasFuncDecl() && (decl.storage_class & STCstatic))
        )
    {
        createGlobalVar(decl, irState);
    }
    else
    {   //create it inside function, or aggregate
        irState->createVar(decl);
        //make a temp state for the initializer
        IRState initState(DEREF(irState).getBlock());
        //initialize static fields inside the aggregate's static init block
        if (decl.storage_class & STCstatic)
        {
            prepStaticInit(irState, initState, decl);
        }

        if (decl.init)
        {
            initState.setDecl(&decl);

#if !VALUETYPE_STRUCT
            TYPE& type = toILType(decl);
            if (StructType* sType = type.isStructType())
            {   //make sure that the struct is not NULL
                BackEnd::construct(decl.loc, *sType);
            }
#endif
            auto_ptr<dt_t> (decl.init->toDt());
        }
        else
        {
            TYPE& t = toILType(decl.loc, decl.type);
            // give static arrays a chance to initialize
            if (t.isArrayType())
            {
                t.initVar(initState, decl, NULL, NULL);
            }
        }
    }
}
예제 #4
0
파일: s2ir.c 프로젝트: Faianca/dmd
    void visit(GotoDefaultStatement *s)
    {
        block *b;
        Blockx *blx = irs->blx;
        block *bdest = irs->getDefaultBlock();

        b = blx->curblock;

        // The rest is equivalent to GotoStatement

        // Adjust exception handler scope index if in different try blocks
        if (b->Btry != bdest->Btry)
        {
            // Check that bdest is in an enclosing try block
            for (block *bt = b->Btry; bt != bdest->Btry; bt = bt->Btry)
            {
                if (!bt)
                {
                    //printf("b->Btry = %p, bdest->Btry = %p\n", b->Btry, bdest->Btry);
                    s->error("cannot goto into try block");
                    break;
                }
            }

            //setScopeIndex(blx, b, bdest->Btry ? bdest->Btry->Bscope_index : -1);
        }

        b->appendSucc(bdest);
        incUsage(irs, s->loc);
        block_next(blx,BCgoto,NULL);
    }
예제 #5
0
파일: modemit.cpp 프로젝트: Geod24/dnet
// Prepare block for static initializer
static void prepStaticInit(IRState* irState, IRState& initState, VarDeclaration& decl)
{
    if (AggregateDeclaration* aggrDecl = irState->hasAggregateDecl())
    {
        if (Class* c = DEREF(aggrDecl->csym).isClass())
        {
            // static members are initialized in a separate block
            // (which is eventually merged into the class' .cctor)
            initState.setBlock(c->getStaticInitBlock());
        }
        else if (Struct* s = DEREF(aggrDecl->csym).isStruct())
        {
            initState.setBlock(s->getStaticInitBlock());
        }
        else 
        {
            BackEnd::fatalError(decl.loc, "unhandled static initializer");
        }
    }
}
예제 #6
0
void TryCatchScope::emitCatchBodiesMSVC(IRState &irs, llvm::Value *) {
  assert(catchBlocks.empty());

  auto &scopes = irs.funcGen().scopes;
  auto &PGO = irs.funcGen().pgo;

  auto catchSwitchBlock = irs.insertBBBefore(endbb, "catch.dispatch");
  llvm::BasicBlock *unwindto =
      scopes.currentCleanupScope() > 0 ? scopes.getLandingPad() : nullptr;
  auto catchSwitchInst = llvm::CatchSwitchInst::Create(
      llvm::ConstantTokenNone::get(irs.context()), unwindto, stmt->catches->dim,
      "", catchSwitchBlock);

  for (auto c : *stmt->catches) {
    auto catchBB =
        irs.insertBBBefore(endbb, llvm::Twine("catch.") + c->type->toChars());

    irs.scope() = IRScope(catchBB);
    irs.DBuilder.EmitBlockStart(c->loc);
    PGO.emitCounterIncrement(c);

    emitBeginCatchMSVC(irs, c, catchSwitchInst);

    // Emit handler, if there is one. The handler is zero, for instance,
    // when building 'catch { debug foo(); }' in non-debug mode.
    if (c->handler)
      Statement_toIR(c->handler, &irs);

    if (!irs.scopereturned())
      irs.ir->CreateBr(endbb);

    irs.DBuilder.EmitBlockEnd();
  }

  scopes.pushCleanup(catchSwitchBlock, catchSwitchBlock);

  // if no landing pad is created, the catch blocks are unused, but
  // the verifier complains if there are catchpads without personality
  // so we can just set it unconditionally
  if (!irs.func()->func->hasPersonalityFn()) {
    const char *personality = "__CxxFrameHandler3";
    LLFunction *personalityFn =
        getRuntimeFunction(Loc(), irs.module, personality);
    irs.func()->func->setPersonalityFn(personalityFn);
  }
}
예제 #7
0
  void visit(LabelStatement *stmt) override {
    IF_LOG Logger::println("LabelStatement::toNakedIR(): %s",
                           stmt->loc.toChars());
    LOG_SCOPE;

    printLabelName(irs->nakedAsm, mangleExact(irs->func()->decl),
                   stmt->ident->toChars());
    irs->nakedAsm << ":";

    if (stmt->statement) {
      stmt->statement->accept(this);
    }
  }
예제 #8
0
파일: s2ir.c 프로젝트: Faianca/dmd
 void visit(CaseStatement *s)
 {
     Blockx *blx = irs->blx;
     block *bcase = blx->curblock;
     Label *clabel = getLabel(irs, blx, s);
     block_next(blx, BCgoto, clabel->lblock);
     block *bsw = irs->getSwitchBlock();
     if (bsw->BC == BCswitch)
         bsw->appendSucc(clabel->lblock);   // second entry in pair
     bcase->appendSucc(clabel->lblock);
     if (blx->tryblock != bsw->Btry)
         s->error("case cannot be in different try block level from switch");
     incUsage(irs, s->loc);
     if (s->statement)
         Statement_toIR(s->statement, irs);
 }
예제 #9
0
파일: s2ir.c 프로젝트: Faianca/dmd
    void visit(BreakStatement *s)
    {
        block *bbreak;
        block *b;
        Blockx *blx = irs->blx;

        bbreak = irs->getBreakBlock(s->ident);
        assert(bbreak);
        b = blx->curblock;
        incUsage(irs, s->loc);

        // Adjust exception handler scope index if in different try blocks
        if (b->Btry != bbreak->Btry)
        {
            //setScopeIndex(blx, b, bbreak->Btry ? bbreak->Btry->Bscope_index : -1);
        }

        /* Nothing more than a 'goto' to the current break destination
         */
        b->appendSucc(bbreak);
        block_setLoc(b, s->loc);
        block_next(blx, BCgoto, NULL);
    }
예제 #10
0
파일: s2ir.c 프로젝트: Faianca/dmd
    void visit(ContinueStatement *s)
    {
        block *bcont;
        block *b;
        Blockx *blx = irs->blx;

        //printf("ContinueStatement::toIR() %p\n", this);
        bcont = irs->getContBlock(s->ident);
        assert(bcont);
        b = blx->curblock;
        incUsage(irs, s->loc);

        // Adjust exception handler scope index if in different try blocks
        if (b->Btry != bcont->Btry)
        {
            //setScopeIndex(blx, b, bcont->Btry ? bcont->Btry->Bscope_index : -1);
        }

        /* Nothing more than a 'goto' to the current continue destination
         */
        b->appendSucc(bcont);
        block_setLoc(b, s->loc);
        block_next(blx, BCgoto, NULL);
    }
예제 #11
0
TryCatchScope::TryCatchScope(IRState &irs, llvm::Value *ehPtrSlot,
                             TryCatchStatement *stmt, llvm::BasicBlock *endbb)
    : stmt(stmt), endbb(endbb) {
  assert(stmt->catches);

  cleanupScope = irs.funcGen().scopes.currentCleanupScope();
  catchesNonExceptions =
      std::any_of(stmt->catches->begin(), stmt->catches->end(), [](Catch *c) {
        for (auto cd = c->type->toBasetype()->isClassHandle(); cd;
             cd = isClassDeclarationOrNull(cd->baseClass)) { // CALYPSO
          if (cd == ClassDeclaration::exception)
            return false;
        }
        return true;
      });

#if LDC_LLVM_VER >= 308
  if (useMSVCEH()) {
    emitCatchBodiesMSVC(irs, ehPtrSlot);
    return;
  }
#endif
  emitCatchBodies(irs, ehPtrSlot);
}
예제 #12
0
파일: s2ir.c 프로젝트: Faianca/dmd
    void visit(ReturnStatement *s)
    {
        Blockx *blx = irs->blx;
        enum BC bc;

        incUsage(irs, s->loc);
        if (s->exp)
        {
            elem *e;

            FuncDeclaration *func = irs->getFunc();
            assert(func);
            assert(func->type->ty == Tfunction);
            TypeFunction *tf = (TypeFunction *)(func->type);

            RET retmethod = retStyle(tf);
            if (retmethod == RETstack)
            {
                elem *es;

                /* If returning struct literal, write result
                 * directly into return value
                 */
                if (s->exp->op == TOKstructliteral)
                {
                    StructLiteralExp *se = (StructLiteralExp *)s->exp;
                    char save[sizeof(StructLiteralExp)];
                    memcpy(save, (void*)se, sizeof(StructLiteralExp));
                    se->sym = irs->shidden;
                    se->soffset = 0;
                    se->fillHoles = 1;
                    e = toElemDtor(s->exp, irs);
                    memcpy((void*)se, save, sizeof(StructLiteralExp));
                }
                else
                    e = toElemDtor(s->exp, irs);
                assert(e);

                if (s->exp->op == TOKstructliteral ||
                    (func->nrvo_can && func->nrvo_var))
                {
                    // Return value via hidden pointer passed as parameter
                    // Write exp; return shidden;
                    es = e;
                }
                else
                {
                    // Return value via hidden pointer passed as parameter
                    // Write *shidden=exp; return shidden;
                    int op;
                    tym_t ety;

                    ety = e->Ety;
                    es = el_una(OPind,ety,el_var(irs->shidden));
                    op = (tybasic(ety) == TYstruct) ? OPstreq : OPeq;
                    es = el_bin(op, ety, es, e);
                    if (op == OPstreq)
                        es->ET = Type_toCtype(s->exp->type);
                }
                e = el_var(irs->shidden);
                e = el_bin(OPcomma, e->Ety, es, e);
            }
            else if (tf->isref)
            {
                // Reference return, so convert to a pointer
                e = toElemDtor(s->exp, irs);
                e = addressElem(e, s->exp->type->pointerTo());
            }
            else
            {
                e = toElemDtor(s->exp, irs);
                assert(e);
            }
            elem_setLoc(e, s->loc);
            block_appendexp(blx->curblock, e);
            bc = BCretexp;
        }
        else
            bc = BCret;

        if (block *finallyBlock = irs->getFinallyBlock())
        {
            assert(finallyBlock->BC == BC_finally);
            blx->curblock->appendSucc(finallyBlock);
        }

        block_next(blx, bc, NULL);
    }
예제 #13
0
파일: IRoom.c 프로젝트: johnsie/IMR
int main( int pArgc, const char** pArgs )
{
   const char* lQueryPtr;
   int         lLock;
   int         lMemId;
   char        lQuery[4096];
   char        lOp[12];
   BOOL        lPrintTitle;


   #ifndef _NO_IPC_
      union semun lNULL;
   #endif

   #ifdef _NO_IPC_
 
      gGlobalState.Clear();
      if( InitLogFile() )
      {
         fprintf( gLogFile, "IMR Init version 0.13.13b %s\n", GetTime( time(NULL)) );
      }

   #endif


   #ifdef _FAST_CGI_
   while( FCGI_Accept() >= 0 )
   {
   #endif
      lPrintTitle = TRUE;

      /* Send the header required by the server */
      printf("Content-type: text/plain%c%c", 10, 10);


      lQueryPtr = getenv( "QUERY_STRING" );

      if( lQueryPtr == NULL )
      {
         printf( "No parameters\n" );
      }
      else
      {

         StrMaxCopy( lQuery, lQueryPtr, 4096 );

         UnpadQuery( lQuery );

         if( sscanf( lQuery, "=%11s", lOp ) == 1 )
         {
            #ifndef _FAST_CGI_
               /* Change the local directory */
               char* lPathEnd = strrchr( pArgs[0], '/' );

               if( lPathEnd != NULL )
               {
                  *lPathEnd = 0;
                  chdir( pArgs[0] );
               }
            #endif


            if( !strcmp( lOp, "RESET" ) )
            {
               printf( "RESET OK\n\n" );

               #ifdef _NO_IPC_
                  /*
                  // gGlobalState.Clear();
                  // sleep( 2 );
                  // return 0;
                  // break;
                  */
               #else

                  lLock  = semget( IR_SEM_KEY, 1, 0777 );
                  lMemId = shmget( IR_SHMEM_KEY, sizeof( IRState ), 0666 );

                  if( lLock != -1 )
                  {
                     semctl( lLock, 0, IPC_RMID, lNULL );
                  }

                  if( lMemId != -1 )
                  {
                     shmctl( lMemId, IPC_RMID, NULL );
                  }

               #endif

               if( InitLogFile() )
               {
                  fprintf( gLogFile, "IMR Reset %s\n", GetTime( time(NULL)) );
               }

               #ifdef _FAST_CGI_
                  break;
               #endif

            }
            else if( !strcmp( lOp, "SET_MESSAGE" ) )
            {
            }
            /*
            else if( !strcmp( lOp, "STICK" ) )
            {
               // Fork and leave a child running for 1 hour

               int lCode = fork();
               if( lCode == 0 )
               {
                  if( InitLogFile() )
                  {
                     fprintf( gLogFile, "STICK Start %s\n", GetTime( time(NULL)) );
                     CloseLogFile();
                  }

                  close( 0 );
                  close( 1 );
                  close( 2 );
                  sleep( 3600 );

                  if( InitLogFile() )
                  {
                     fprintf( gLogFile, "STICK End %s\n", GetTime( time(NULL)) );
                     CloseLogFile();
                  }

               }
               
               else if( lCode == -1 )
               {
                  printf( "ERROR\n" );
               }
               else
               {
                  printf( "SUCCESS\n" );
               }
               
            }
            */
            else
            {
               IRState* lState = NULL;

               #ifdef _NO_IPC_
                  lState = &gGlobalState;

               #else

                  int      lLock;        /* Semaphore */
                  int      lMemId;       /* Shared memory */

                  struct sembuf lSemOp;

                  lSemOp.sem_flg = 0;  /*Avoid corruption but must not core-dump SEM_UNDO;  // Risky but prevents dead-lock */
                  lSemOp.sem_num  = 0;

                  /* First try to create the structure for the first time */
                  /* Lock the data struct */
                  lLock = semget( IR_SEM_KEY, 1, 0777|IPC_CREAT|IPC_EXCL );

                  if( lLock != -1 )
                  {
                     union semun lArg;
               
                     /* Initialize the newly created semaphore */
                     lArg.val = 1;
 
                     semctl( lLock, 0, SETVAL, lArg );
                  }
                  else
                  {
                     lLock = semget( IR_SEM_KEY, 1, 0777 );
                  }

                  if( lLock == -1 )
                  {
                     printf( "Unable to get semaphore\n" );
                  }
                  else
                  {
                     lSemOp.sem_op   = -1;

                     if( semop( lLock, &lSemOp, 1 ) == -1 )
                     {
                        printf( "Unable to decrement semaphore\n" );
                        lLock = -1;
                     }
                     else
                     {

                        /* From here we can work safely */

                        lMemId = shmget( IR_SHMEM_KEY, sizeof( IRState ), 0666|IPC_CREAT|IPC_EXCL );

                        if( lMemId != -1 )
                        {
                           lState = (IRState*)shmat( lMemId, NULL, 0 );

                           if( (int)lState == -1 )
                           {
                              lState = NULL;
                           }

                           if( lState == NULL )
                           {
                              printf( "Unable to attach shmem\n" );
                           }
                           else
                           {
                              Clear( lState );

                              if( InitLogFile() )
                              {
                                 fprintf( gLogFile, "IMR Init %s\n", GetTime( time(NULL)) );
                              }

                           }
                        }
                        else
                        {
                           lMemId = shmget( IR_SHMEM_KEY, sizeof( IRState ), 0666 );

                           if( lMemId == -1 )
                           {
                              printf( "Unable to get shmem\n" );
                           }
                           else
                           {
                              lState = (IRState*)shmat( lMemId, NULL, 0 );

                              if( (int)lState == -1 )
                              {
                                 lState = NULL;
                              }

                              if( lState == NULL )
                              {
                                 printf( "Unable to attach shmem\n" );
                              }
                           }
                        }
                     }
                  }

               #endif
   
               if( lState != NULL )
               {

                  lPrintTitle = FALSE;

                  VerifyExpirations( lState );

                  if( !strcmp( lOp, "REFRESH" ) )
                  {
                     int lUserIndex;
                     int lUserId;
                     int lTimeStamp;

                     if( sscanf( lQuery, "%*s %d-%u %d", &lUserIndex, &lUserId, &lTimeStamp )==3 )
                     {
                        PrintStateChange( lState, lUserIndex, lUserId, lTimeStamp );
                     }
                  }
                  else if( !strcmp( lOp, "ADD_CHAT" ) )
                  {
                     int  lUserIndex;
                     int  lUserId;
                     char lChatMessage[200];

                     if( sscanf( lQuery, "%*s %d-%u %200s", &lUserIndex, &lUserId, lChatMessage )==3 )
                     {
                        Unpad( lChatMessage );
                        AddChatMessage( lState, lUserIndex, lUserId, lChatMessage );
                     }
                  }
                  /*   URL?=ADD_USER MAJOR-MINORID VERSION KEY2 KEY3 ALIAS */
                  else if( !strcmp( lOp, "ADD_USER" ) )
                  {
                     int lMajorID;
                     int lMinorID;
                     int  lVersion;
                     unsigned int lKey2;
                     unsigned int lKey3;
                     char lUserName[40];

                     #ifdef _EXPIRED_ 
                        AddUser(  lState, "User", 1,-1, -1, 0, 0  );
                     #else
                        if( sscanf( lQuery, "%*s %d-%d %d %d %d %40s", &lMajorID, &lMinorID, &lVersion, &lKey2, &lKey3, lUserName )==6 )
                        {
                           Unpad( lUserName );
                           AddUser( lState, lUserName, lVersion,lMajorID, lMinorID, lKey2, lKey3  );
                        }
                     #endif
                  }
                  /* URL?=ADD_GAME USER_ID GAME_NAME TRACK_NAME NBLAP WEAPON PORT */
                  else if( !strcmp( lOp, "ADD_GAME" ) )
                  {
                     int       lUserIndex;
                     int       lUserId;
                     int       lNbLap;
                     char      lGameName[40];
                     char      lTrackName[40];
                     int       lWeapon;
                     unsigned  lPort;
               
                     if( sscanf( lQuery, "%*s %d-%u %40s %40s %d %d %u", &lUserIndex, &lUserId, lGameName, lTrackName, &lNbLap, &lWeapon, &lPort )==7 )
                     {
                        const char* lRemoteAddr = getenv( "REMOTE_ADDR" );

                        if( (lRemoteAddr != NULL)&&(strlen(lRemoteAddr) != 0) )
                        {
                           Unpad( lTrackName );
                           Unpad( lGameName );
                           AddGame( lState, lGameName, lTrackName, lNbLap, lUserIndex, lUserId, lRemoteAddr, lPort, lWeapon  );
                        }
                     }
                  }
                  else if( !strcmp( lOp, "JOIN_GAME" ) )
                  {
                     int   lUserIndex;
                     int   lUserId;
                     int   lGameIndex;
                     int   lGameId;
               
                     if( sscanf( lQuery, "%*s %d-%u %d-%u", &lGameIndex, &lGameId, &lUserIndex, &lUserId )==4 )
                     {
                        JoinGame( lState, lGameIndex, lGameId, lUserIndex, lUserId );
                     }
                  }
                  else if( !strcmp( lOp, "DEL_GAME" ) )
                  {
                     int   lUserIndex;
                     int   lUserId;
                     int   lGameIndex;
                     int   lGameId;
               
                     if( sscanf( lQuery, "%*s %d-%u %d-%u", &lGameIndex, &lGameId, &lUserIndex, &lUserId )==4 )
                     {
                        DeleteGame( lState, lGameIndex, lGameId, lUserIndex, lUserId );
                     }
                  }
                  else if( !strcmp( lOp, "LEAVE_GAME" ) )
                  {
                     int   lUserIndex;
                     int   lUserId;
                     int   lGameIndex;
                     int   lGameId;
               
                     if( sscanf( lQuery, "%*s %d-%u %d-%u", &lGameIndex, &lGameId, &lUserIndex, &lUserId )==4 )
                     {
                        LeaveGame( lState, lGameIndex, lGameId, lUserIndex, lUserId );
                     }
                  }
                  else if( !strcmp( lOp, "DEL_USER" ) )
                  {
                     int   lUserIndex;
                     int   lUserId;
               
                     if( sscanf( lQuery, "%*s %d-%u", &lUserIndex, &lUserId )==2 )
                     {
                        DeleteUser( lState, lUserIndex, lUserId );
                     }
                  }
                  else if( !strcmp( lOp, "START_GAME" ) )
                  {
                     int   lUserIndex;
                     int   lUserId;
                     int   lGameIndex;
                     int   lGameId;
               
                     if( sscanf( lQuery, "%*s %d-%u %d-%u", &lGameIndex, &lGameId, &lUserIndex, &lUserId )==4 )
                     {
                        StartGame( lState, lGameIndex, lGameId, lUserIndex, lUserId );
                     }
                  }
                  else
                  {
                     lPrintTitle = TRUE;
                  }
               }

               #ifdef _NO_IPC_
                  lState = NULL;
               #else
                  /* Release lock */
                  if( lLock != -1 )
                  {
                     lSemOp.sem_op   = 1;

                     semop( lLock, &lSemOp, 1 );

                     /* Release memory */
                     if( lState != NULL )
                     {
                        shmdt( (char*)lState );
                     }
                  }
                  
               #endif
               
            }
         }
      }

      CloseLogFile();

      if( lPrintTitle )
      {
         printf( "Internet Meeting Room (c)1996,97 GrokkSoft inc.\n" );
      }
  #ifdef _FAST_CGI_
  }
  #endif

   return 0;
}
예제 #14
0
void TryCatchScope::emitCatchBodies(IRState &irs, llvm::Value *ehPtrSlot) {
  assert(catchBlocks.empty());

  auto &PGO = irs.funcGen().pgo;
  const auto entryCount = PGO.setCurrentStmt(stmt);

  struct CBPrototype {
    Type *t;
    llvm::BasicBlock *catchBB;
    uint64_t catchCount;
    uint64_t uncaughtCount;
  };
  llvm::SmallVector<CBPrototype, 8> cbPrototypes;
  cbPrototypes.reserve(stmt->catches->dim);

  for (auto c : *stmt->catches) {
    auto catchBB =
        irs.insertBBBefore(endbb, llvm::Twine("catch.") + c->type->toChars());
    irs.scope() = IRScope(catchBB);
    irs.DBuilder.EmitBlockStart(c->loc);
    PGO.emitCounterIncrement(c);

    bool isCPPclass = false;

    if (auto lp = c->langPlugin()) // CALYPSO
      lp->codegen()->toBeginCatch(irs, c);
    else
    {

    const auto cd = c->type->toBasetype()->isClassHandle();
    isCPPclass = cd->isCPPclass();

    const auto enterCatchFn = getRuntimeFunction(
        Loc(), irs.module,
        isCPPclass ? "__cxa_begin_catch" : "_d_eh_enter_catch");
    const auto ptr = DtoLoad(ehPtrSlot);
    const auto throwableObj = irs.ir->CreateCall(enterCatchFn, ptr);

    // For catches that use the Throwable object, create storage for it.
    // We will set it in the code that branches from the landing pads
    // (there might be more than one) to catchBB.
    if (c->var) {
      // This will alloca if we haven't already and take care of nested refs
      // if there are any.
      DtoDeclarationExp(c->var);

      // Copy the exception reference over from the _d_eh_enter_catch return
      // value.
      DtoStore(DtoBitCast(throwableObj, DtoType(c->var->type)),
               getIrLocal(c->var)->value);
    }
    }

    // Emit handler, if there is one. The handler is zero, for instance,
    // when building 'catch { debug foo(); }' in non-debug mode.
    if (isCPPclass) {
      // from DMD:

      /* C++ catches need to end with call to __cxa_end_catch().
       * Create:
       *   try { handler } finally { __cxa_end_catch(); }
       * Note that this is worst case code because it always sets up an
       * exception handler. At some point should try to do better.
       */
      FuncDeclaration *fdend =
          FuncDeclaration::genCfunc(nullptr, Type::tvoid, "__cxa_end_catch");
      Expression *efunc = VarExp::create(Loc(), fdend);
      Expression *ecall = CallExp::create(Loc(), efunc);
      ecall->type = Type::tvoid;
      Statement *call = ExpStatement::create(Loc(), ecall);
      Statement *stmt =
          c->handler ? TryFinallyStatement::create(Loc(), c->handler, call)
                     : call;
      Statement_toIR(stmt, &irs);
    } else {
      if (c->handler)
        Statement_toIR(c->handler, &irs);
    }

    if (!irs.scopereturned())
    {
      // CALYPSO FIXME: _cxa_end_catch won't be called if it has already returned
      if (auto lp = c->langPlugin())
        lp->codegen()->toEndCatch(irs, c);
      irs.ir->CreateBr(endbb);
    }

    irs.DBuilder.EmitBlockEnd();

    // PGO information, currently unused
    auto catchCount = PGO.getRegionCount(c);
    // uncaughtCount is handled in a separate pass below

    cbPrototypes.push_back({c->type->toBasetype(), catchBB, catchCount, 0}); // CALYPSO
  }

  // Total number of uncaught exceptions is equal to the execution count at
  // the start of the try block minus the one after the continuation.
  // uncaughtCount keeps track of the exception type mismatch count while
  // iterating through the catch block prototypes in reversed order.
  auto uncaughtCount = entryCount - PGO.getRegionCount(stmt);
  for (auto it = cbPrototypes.rbegin(), end = cbPrototypes.rend(); it != end;
       ++it) {
    it->uncaughtCount = uncaughtCount;
    // Add this catch block's match count to the uncaughtCount, because these
    // failed to match the remaining (lexically preceding) catch blocks.
    uncaughtCount += it->catchCount;
  }

  catchBlocks.reserve(stmt->catches->dim);

  auto c_it = stmt->catches->begin(); // CALYPSO
  for (const auto &p : cbPrototypes) {
    auto branchWeights =
        PGO.createProfileWeights(p.catchCount, p.uncaughtCount);
    LLGlobalVariable *ci;
    if (auto lp = (*c_it)->langPlugin()) // CALYPSO
      ci = lp->codegen()->toCatchScopeType(irs, p.t);
    else {
      ClassDeclaration *cd = p.t->isClassHandle();
      DtoResolveClass(cd);
      if (cd->isCPPclass()) {
        const char *name = Target::cppTypeInfoMangle(cd);
        auto cpp_ti = getOrCreateGlobal(
            cd->loc, irs.module, getVoidPtrType(), /*isConstant=*/true,
            LLGlobalValue::ExternalLinkage, /*init=*/nullptr, name);

        // Wrap std::type_info pointers inside a __cpp_type_info_ptr class instance so that
        // the personality routine may differentiate C++ catch clauses from D ones.
        OutBuffer mangleBuf;
        mangleBuf.writestring("_D");
        mangleToBuffer(cd, &mangleBuf);
        mangleBuf.printf("%d%s", 18, "_cpp_type_info_ptr");
        const auto wrapperMangle = getIRMangledVarName(mangleBuf.peekString(), LINKd);

        RTTIBuilder b(ClassDeclaration::cpp_type_info_ptr);
        b.push(cpp_ti);

        auto wrapperType = llvm::cast<llvm::StructType>(
            static_cast<IrTypeClass*>(ClassDeclaration::cpp_type_info_ptr->type->ctype)->getMemoryLLType());
        auto wrapperInit = b.get_constant(wrapperType);

        ci = getOrCreateGlobal(
            cd->loc, irs.module, wrapperType, /*isConstant=*/true,
            LLGlobalValue::LinkOnceODRLinkage, wrapperInit, wrapperMangle);
      } else {
        ci = getIrAggr(cd)->getClassInfoSymbol();
      }
    }
    catchBlocks.push_back({ci, p.catchBB, branchWeights});
    c_it++;
  }
}
예제 #15
0
void TryCatchScope::emitCatchBodies(IRState &irs, llvm::Value *ehPtrSlot) {
  assert(catchBlocks.empty());

  auto &PGO = irs.funcGen().pgo;
  const auto entryCount = PGO.setCurrentStmt(stmt);

  struct CBPrototype {
    ClassDeclaration *cd;
    llvm::BasicBlock *catchBB;
    uint64_t catchCount;
    uint64_t uncaughtCount;
  };
  llvm::SmallVector<CBPrototype, 8> cbPrototypes;
  cbPrototypes.reserve(stmt->catches->dim);

  for (auto c : *stmt->catches) {
    auto catchBB =
        irs.insertBBBefore(endbb, llvm::Twine("catch.") + c->type->toChars());
    irs.scope() = IRScope(catchBB);
    irs.DBuilder.EmitBlockStart(c->loc);
    PGO.emitCounterIncrement(c);

    const auto enterCatchFn =
        getRuntimeFunction(Loc(), irs.module, "_d_eh_enter_catch");
    auto ptr = DtoLoad(ehPtrSlot);
    auto throwableObj = irs.ir->CreateCall(enterCatchFn, ptr);

    // For catches that use the Throwable object, create storage for it.
    // We will set it in the code that branches from the landing pads
    // (there might be more than one) to catchBB.
    if (c->var) {
      // This will alloca if we haven't already and take care of nested refs
      // if there are any.
      DtoDeclarationExp(c->var);

      // Copy the exception reference over from the _d_eh_enter_catch return
      // value.
      DtoStore(DtoBitCast(throwableObj, DtoType(c->var->type)),
               getIrLocal(c->var)->value);
    }

    // Emit handler, if there is one. The handler is zero, for instance,
    // when building 'catch { debug foo(); }' in non-debug mode.
    if (c->handler)
      Statement_toIR(c->handler, &irs);

    if (!irs.scopereturned())
      irs.ir->CreateBr(endbb);

    irs.DBuilder.EmitBlockEnd();

    // PGO information, currently unused
    auto catchCount = PGO.getRegionCount(c);
    // uncaughtCount is handled in a separate pass below

    auto cd = c->type->toBasetype()->isClassHandle();
    cbPrototypes.push_back({cd, catchBB, catchCount, 0});
  }

  // Total number of uncaught exceptions is equal to the execution count at
  // the start of the try block minus the one after the continuation.
  // uncaughtCount keeps track of the exception type mismatch count while
  // iterating through the catch block prototypes in reversed order.
  auto uncaughtCount = entryCount - PGO.getRegionCount(stmt);
  for (auto it = cbPrototypes.rbegin(), end = cbPrototypes.rend(); it != end;
       ++it) {
    it->uncaughtCount = uncaughtCount;
    // Add this catch block's match count to the uncaughtCount, because these
    // failed to match the remaining (lexically preceding) catch blocks.
    uncaughtCount += it->catchCount;
  }

  catchBlocks.reserve(stmt->catches->dim);

  for (const auto &p : cbPrototypes) {
    auto branchWeights =
        PGO.createProfileWeights(p.catchCount, p.uncaughtCount);
    DtoResolveClass(p.cd);
    auto ci = getIrAggr(p.cd)->getClassInfoSymbol();
    catchBlocks.push_back({ci, p.catchBB, branchWeights});
  }
}