예제 #1
0
 CG::ExprValue ConstFloat::buildExprValue( CG::BasicBlockBuilder &basicBlockBuilder, CG::Usage usage, std::string const &lValueErrorDesc ) const
 {
   if ( usage == CG::USAGE_LVALUE )
     throw Exception( "constants cannot be used as l-values" );
   RC::ConstHandle<CG::FloatAdapter> floatAdapter = basicBlockBuilder.getManager()->getFloat64Adapter();
   floatAdapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() );
   double value = Util::parseDouble( m_valueString );
   return CG::ExprValue( floatAdapter, CG::USAGE_RVALUE, basicBlockBuilder.getContext(), floatAdapter->llvmConst( basicBlockBuilder.getContext(), value ) );
 }
예제 #2
0
 CG::ExprValue ConstString::buildExprValue( CG::BasicBlockBuilder &basicBlockBuilder, CG::Usage usage, std::string const &lValueErrorDesc ) const
 {
   if ( usage == CG::USAGE_LVALUE )
     throw Exception( "constants cannot be used as l-values" );
   std::string unquotedValue;
   try
   {
     unquotedValue = Util::parseQuotedString( m_value );
   }
   catch ( Exception e )
   {
     throw CG::Error( getLocation(), e.getDesc() + "(" + m_value + ")" );
   }
   RC::ConstHandle<CG::ConstStringAdapter> constStringAdapter = basicBlockBuilder.getManager()->getConstStringAdapter();
   constStringAdapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() );
   RC::ConstHandle<CG::StringAdapter> stringAdapter = basicBlockBuilder.getManager()->getStringAdapter();
   stringAdapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() );
   return CG::ExprValue( constStringAdapter, CG::USAGE_RVALUE, basicBlockBuilder.getContext(), constStringAdapter->llvmConst( basicBlockBuilder, unquotedValue.data(), unquotedValue.length() ) ).castTo( basicBlockBuilder, stringAdapter );
 }
예제 #3
0
 CG::ExprType MethodOp::getExprType( CG::BasicBlockBuilder &basicBlockBuilder ) const
 {
   RC::ConstHandle<CG::Adapter> adapter = getFunction( basicBlockBuilder )->getReturnInfo().getAdapter();
   if ( adapter )
   {
     adapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() );
     return CG::ExprType( adapter, CG::USAGE_RVALUE );
   }
   else return CG::ExprType();
 }
예제 #4
0
 CG::ExprType IndexOp::getExprType( CG::BasicBlockBuilder &basicBlockBuilder ) const
 {
   CG::ExprType exprType = m_expr->getExprType( basicBlockBuilder );
   exprType.getAdapter()->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() );
   
   if ( RT::isArray( exprType.getAdapter()->getType() ) )
   {
     RC::ConstHandle<CG::ArrayAdapter> arrayType = RC::ConstHandle<CG::ArrayAdapter>::StaticCast( exprType.getAdapter() );
     
     RC::ConstHandle<CG::Adapter> memberAdapter = arrayType->getMemberAdapter();
     memberAdapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() );
     return CG::ExprType( memberAdapter, exprType.getUsage() );
   }
   else if ( RT::isDict( exprType.getAdapter()->getType() ) )
   {
     RC::ConstHandle<CG::DictAdapter> dictType = RC::ConstHandle<CG::DictAdapter>::StaticCast( exprType.getAdapter() );
     
     RC::ConstHandle<CG::Adapter> valueAdapter = dictType->getValueAdapter();
     valueAdapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() );
     return CG::ExprType( valueAdapter, exprType.getUsage() );
   }
   else throw Exception( "only arrays and dictionaries can be indexed" );
 }
예제 #5
0
    void Report::llvmCompileToBuilder( CG::BasicBlockBuilder &basicBlockBuilder, CG::Diagnostics &diagnostics ) const
    {
      RC::ConstHandle< CG::StringAdapter > stringAdapter = basicBlockBuilder.getManager()->getStringAdapter();
      stringAdapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() );

      try
      {
        CG::Scope subScope( basicBlockBuilder.getScope() );
        CG::BasicBlockBuilder subBBB( basicBlockBuilder, subScope );
        CG::ExprValue exprExprValue = m_expr->buildExprValue( subBBB, CG::USAGE_RVALUE, "cannot be an l-value" );
        llvm::Value *stringRValue = stringAdapter->llvmCast( subBBB, exprExprValue );
        stringAdapter->llvmReport( subBBB, stringRValue );
        subScope.llvmUnwind( subBBB );
      }
      catch ( CG::Error e )
      {
        addError( diagnostics, e );
      }
      catch ( Exception e )
      {
        addError( diagnostics, e );
      }
    }
예제 #6
0
 CG::ExprType ConstString::getExprType( CG::BasicBlockBuilder &basicBlockBuilder ) const
 {
   RC::ConstHandle<CG::Adapter> adapter = basicBlockBuilder.getManager()->getStringAdapter();
   adapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() );
   return CG::ExprType( adapter, CG::USAGE_RVALUE );
 }
    void ArrayProducerAdapter::llvmCompileToModule( ModuleBuilder &moduleBuilder ) const
    {
      if ( moduleBuilder.haveCompiledToModule( getCodeName() ) )
        return;
        
      RC::Handle<Context> context = moduleBuilder.getContext();
      
      m_elementAdapter->llvmCompileToModule( moduleBuilder );
      m_elementVariableArrayAdapter->llvmCompileToModule( moduleBuilder );
      RC::ConstHandle<BooleanAdapter> booleanAdapter = getManager()->getBooleanAdapter();
      booleanAdapter->llvmCompileToModule( moduleBuilder );
      RC::ConstHandle<SizeAdapter> sizeAdapter = getManager()->getSizeAdapter();
      sizeAdapter->llvmCompileToModule( moduleBuilder );
      RC::ConstHandle<StringAdapter> stringAdapter = getManager()->getStringAdapter();
      stringAdapter->llvmCompileToModule( moduleBuilder );
      RC::ConstHandle<ConstStringAdapter> constStringAdapter = getManager()->getConstStringAdapter();
      constStringAdapter->llvmCompileToModule( moduleBuilder );      
            
      static const bool buildFunctions = true;
      
      {
        ConstructorBuilder functionBuilder( moduleBuilder, stringAdapter, this, ConstructorBuilder::HighCost );
        if ( buildFunctions )
        {
          llvm::Value *stringLValue = functionBuilder[0];
          BasicBlockBuilder basicBlockBuilder( functionBuilder );
          
          basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
          std::string name = getUserName();
          ExprValue exprValue( constStringAdapter, USAGE_RVALUE, context, constStringAdapter->llvmConst( basicBlockBuilder, name.data(), name.length() ) );
          llvm::Value *stringRValue = stringAdapter->llvmCast( basicBlockBuilder, exprValue );
          stringAdapter->llvmAssign( basicBlockBuilder, stringLValue, stringRValue );
          stringAdapter->llvmDispose( basicBlockBuilder, stringRValue );
          basicBlockBuilder->CreateRetVoid();
        }
      }
   
      {
        ConstructorBuilder functionBuilder( moduleBuilder, booleanAdapter, this, ConstructorBuilder::HighCost );
        if ( buildFunctions )
        {
          llvm::Value *booleanLValue = functionBuilder[0];
          llvm::Value *rValue = functionBuilder[1];
          BasicBlockBuilder basicBlockBuilder( functionBuilder );
          basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
          llvm::Value *arrayProducerRValue = basicBlockBuilder->CreateLoad( rValue );
          basicBlockBuilder->CreateStore(
            basicBlockBuilder->CreateIsNotNull( arrayProducerRValue ),
            booleanLValue
            );
          basicBlockBuilder->CreateRetVoid();
        }
      }

      {
        MethodBuilder functionBuilder( moduleBuilder, sizeAdapter, this, USAGE_RVALUE, "getCount" );
        if ( buildFunctions )
        {
          BasicBlockBuilder basicBlockBuilder( functionBuilder );

          llvm::Value *rValue = functionBuilder[0];

          llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" );
          
          basicBlockBuilder->SetInsertPoint( entryBB );
          basicBlockBuilder->CreateRet(
            llvmGetCount( basicBlockBuilder, rValue )
            );
        }
      }

      {
        MethodBuilder functionBuilder(
          moduleBuilder,
          m_elementVariableArrayAdapter,
          this, USAGE_RVALUE,
          "produce"
          );
        if ( buildFunctions )
        {
          BasicBlockBuilder basicBlockBuilder( functionBuilder );

          llvm::Value *rValue = functionBuilder[0];

          llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" );
          
          basicBlockBuilder->SetInsertPoint( entryBB );
          llvmProduce0( basicBlockBuilder, rValue, functionBuilder.getScope().llvmGetReturnLValue() );
          basicBlockBuilder->CreateRetVoid();
        }
      }

      {
        MethodBuilder functionBuilder(
          moduleBuilder, m_elementAdapter,
          this, USAGE_RVALUE,
          "produce",
          "index", sizeAdapter, USAGE_RVALUE
          );
        if ( buildFunctions )
        {
          BasicBlockBuilder basicBlockBuilder( functionBuilder );

          llvm::Value *rValue = functionBuilder[0];
          llvm::Value *indexRValue = functionBuilder[1];

          llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" );
          
          basicBlockBuilder->SetInsertPoint( entryBB );
          CG::FunctionScope &functionScope = functionBuilder.getScope();
          functionScope.llvmPrepareReturnLValue( basicBlockBuilder );
          llvmProduce1( basicBlockBuilder, rValue, indexRValue, functionScope.llvmGetReturnLValue() );
          if ( functionScope.getReturnInfo().usesReturnLValue() )
            basicBlockBuilder->CreateRetVoid();
          else
            basicBlockBuilder->CreateRet( basicBlockBuilder->CreateLoad( functionScope.llvmGetReturnLValue() ) );
        }
      }

      {
        MethodBuilder functionBuilder(
          moduleBuilder, m_elementVariableArrayAdapter,
          this, USAGE_RVALUE,
          "produce",
          "index", sizeAdapter, USAGE_RVALUE,
          "count", sizeAdapter, USAGE_RVALUE
          );
        if ( buildFunctions )
        {
          BasicBlockBuilder basicBlockBuilder( functionBuilder );

          llvm::Value *rValue = functionBuilder[0];
          llvm::Value *indexRValue = functionBuilder[1];
          llvm::Value *countRValue = functionBuilder[2];

          llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" );
          
          basicBlockBuilder->SetInsertPoint( entryBB );
          llvmProduce2( basicBlockBuilder, rValue, indexRValue, countRValue, functionBuilder.getScope().llvmGetReturnLValue() );
          basicBlockBuilder->CreateRetVoid();
        }
      }
      
      {
        MethodBuilder functionBuilder( moduleBuilder, 0, this, USAGE_RVALUE, "flush" );
        if ( buildFunctions )
        {
          BasicBlockBuilder basicBlockBuilder( functionBuilder );

          llvm::Value *rValue = functionBuilder[0];

          llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" );
          
          basicBlockBuilder->SetInsertPoint( entryBB );

          llvmFlush( basicBlockBuilder, rValue );
          basicBlockBuilder->CreateRetVoid();
        }
      }
    }
예제 #8
0
 void OpaqueAdapter::llvmCompileToModule( ModuleBuilder &moduleBuilder ) const
 {
   if ( moduleBuilder.haveCompiledToModule( getCodeName() ) )
     return;
   
   RC::Handle<Context> context = moduleBuilder.getContext();
   
   RC::ConstHandle<BooleanAdapter> booleanAdapter = getManager()->getBooleanAdapter();
   booleanAdapter->llvmCompileToModule( moduleBuilder );
   RC::ConstHandle<SizeAdapter> sizeAdapter = getManager()->getSizeAdapter();
   sizeAdapter->llvmCompileToModule( moduleBuilder );
   RC::ConstHandle<StringAdapter> stringAdapter = getManager()->getStringAdapter();
   stringAdapter->llvmCompileToModule( moduleBuilder );
   RC::ConstHandle<OpaqueAdapter> dataAdapter = getManager()->getDataAdapter();
   dataAdapter->llvmCompileToModule( moduleBuilder );
   
   static const bool buildFunctions = true;
   
   {
     ConstructorBuilder functionBuilder( moduleBuilder, booleanAdapter, this, ConstructorBuilder::HighCost );
     if ( buildFunctions )
     {
       llvm::Value *booleanLValue = functionBuilder[0];
       llvm::Value *opaqueRValue = functionBuilder[1];
       BasicBlockBuilder basicBlockBuilder( functionBuilder );
       basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
       llvm::Value *booleanRValue = basicBlockBuilder->CreateIsNotNull( opaqueRValue );
       booleanAdapter->llvmAssign( basicBlockBuilder, booleanLValue, booleanRValue );
       basicBlockBuilder->CreateRetVoid();
     }
   }
   
   {
     ConstructorBuilder functionBuilder( moduleBuilder, stringAdapter, this, ConstructorBuilder::HighCost );
     if ( buildFunctions )
     {
       llvm::Value *stringLValue = functionBuilder[0];
       llvm::Value *opaqueRValue = functionBuilder[1];
       BasicBlockBuilder basicBlockBuilder( functionBuilder );
       basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
       llvm::Value *opaqueLValue = llvmRValueToLValue( basicBlockBuilder, opaqueRValue );
       stringAdapter->llvmCallCast( basicBlockBuilder, this, opaqueLValue, stringLValue );
       basicBlockBuilder->CreateRetVoid();
     }
   }
   
   {
     MethodBuilder functionBuilder(
       moduleBuilder,
       sizeAdapter,
       this, USAGE_RVALUE,
       "dataSize"
       );
     if ( buildFunctions )
     {
       BasicBlockBuilder basicBlockBuilder( functionBuilder );
       basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
       llvm::Value *dataSizeRValue = sizeAdapter->llvmConst( context, getDesc()->getAllocSize() );
       basicBlockBuilder->CreateRet( dataSizeRValue );
     }
   }
   
   {
     MethodBuilder functionBuilder(
       moduleBuilder,
       dataAdapter,
       this, USAGE_LVALUE,
       "data"
       );
     if ( buildFunctions )
     {
       llvm::Value *thisLValue = functionBuilder[0];
       BasicBlockBuilder basicBlockBuilder( functionBuilder );
       basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
       basicBlockBuilder->CreateRet( basicBlockBuilder->CreatePointerCast( thisLValue, dataAdapter->llvmRType( context ) ) );
     }
   }
 }
예제 #9
0
 void StructAdapter::llvmCompileToModule( ModuleBuilder &moduleBuilder ) const
 {
   if ( moduleBuilder.haveCompiledToModule( getCodeName() ) )
     return;
     
   RC::Handle<Context> context = moduleBuilder.getContext();
   
   RC::ConstHandle<StringAdapter> stringAdapter = getManager()->getStringAdapter();
   stringAdapter->llvmCompileToModule( moduleBuilder );
   RC::ConstHandle<SizeAdapter> sizeAdapter = getManager()->getSizeAdapter();
   sizeAdapter->llvmCompileToModule( moduleBuilder );
   RC::ConstHandle<OpaqueAdapter> dataAdapter = getManager()->getDataAdapter();
   dataAdapter->llvmCompileToModule( moduleBuilder );
   for ( MemberAdaptorVector::const_iterator it=m_memberAdapters.begin(); it!=m_memberAdapters.end(); ++it )
     (*it)->llvmCompileToModule( moduleBuilder );
   
   static const bool buildFunctions = true;
   
   if ( !m_isShallow )
   {
     {
       InternalFunctionBuilder functionBuilder(
         moduleBuilder,
         0, "__" + getCodeName() + "__DefaultAssign",
         "dst", this, USAGE_LVALUE,
         "src", this, USAGE_RVALUE,
         0
         );
       if ( buildFunctions )
       {
         llvm::Value *dstLValue = functionBuilder[0];
         llvm::Value *srcRValue = functionBuilder[1];
         BasicBlockBuilder basicBlockBuilder( functionBuilder );
         basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
         for ( size_t i=0; i<getNumMembers(); ++i )
         {
           RC::ConstHandle<Adapter> const &memberAdapter = m_memberAdapters[i];
           llvm::Value *dstMemberLValue = basicBlockBuilder->CreateConstGEP2_32( dstLValue, 0, i );
           llvm::Value *srcMemberLValue = basicBlockBuilder->CreateConstGEP2_32( srcRValue, 0, i );
           llvm::Value *srcMemberRValue = memberAdapter->llvmLValueToRValue( basicBlockBuilder, srcMemberLValue );
           memberAdapter->llvmAssign( basicBlockBuilder, dstMemberLValue, srcMemberRValue );
         }
         basicBlockBuilder->CreateRetVoid();
       }
     }
   }
   
   {
     ConstructorBuilder functionBuilder( moduleBuilder, stringAdapter, this, ConstructorBuilder::HighCost );
     if ( buildFunctions )
     {
       llvm::Value *stringLValue = functionBuilder[0];
       llvm::Value *structRValue = functionBuilder[1];
       BasicBlockBuilder basicBlockBuilder( functionBuilder );
       basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
       llvm::Value *structLValue = llvmRValueToLValue( basicBlockBuilder, structRValue );
       stringAdapter->llvmCallCast( basicBlockBuilder, this, structLValue, stringLValue );
       basicBlockBuilder->CreateRetVoid();
     }
   }
   
   if ( getDesc()->isShallow() )
   {
     {
       MethodBuilder functionBuilder(
         moduleBuilder,
         sizeAdapter,
         this, USAGE_RVALUE,
         "dataSize"
         );
       if ( buildFunctions )
       {
         BasicBlockBuilder basicBlockBuilder( functionBuilder );
         basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
         llvm::Value *dataSizeRValue = llvm::ConstantInt::get( sizeAdapter->llvmRType( context ), getDesc()->getAllocSize() );
         basicBlockBuilder->CreateRet( dataSizeRValue );
       }
     }
     
     {
       MethodBuilder functionBuilder(
         moduleBuilder,
         dataAdapter,
         this, USAGE_LVALUE,
         "data"
         );
       if ( buildFunctions )
       {
         llvm::Value *thisLValue = functionBuilder[0];
         BasicBlockBuilder basicBlockBuilder( functionBuilder );
         basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
         basicBlockBuilder->CreateRet( basicBlockBuilder->CreatePointerCast( thisLValue, dataAdapter->llvmRType( context ) ) );
       }
     }
   }
 }