Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Waitfor.cc

    r310e5b7 re3e16bc  
    2727#include "InitTweak/InitTweak.h"   // for getPointerBase
    2828#include "Parser/LinkageSpec.h"    // for Cforall
    29 #include "ResolvExpr/Resolver.h"   // for findVoidExpression
     29#include "SymTab/AddVisit.h"       // for acceptAndAdd
    3030#include "SynTree/Constant.h"      // for Constant
    3131#include "SynTree/Declaration.h"   // for StructDecl, FunctionDecl, ObjectDecl
     
    112112        //=============================================================================================
    113113
    114         class GenerateWaitForPass final : public WithIndexer {
     114        class GenerateWaitForPass final : public WithStmtsToAdd {
    115115          public:
    116116
     
    129129                void         init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt );
    130130                Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, CompoundStmt * stmt );
    131                 Expression * call(size_t count, ObjectDecl * acceptables, Expression * timeout, CompoundStmt * stmt);
    132                 void         choose( WaitForStmt * waitfor, Expression  * result, CompoundStmt * stmt );
     131                Expression * call();
     132                void choose();
    133133
    134134                static void implement( std::list< Declaration * > & translationUnit ) {
     
    142142                StructDecl          * decl_acceptable = nullptr;
    143143                StructDecl          * decl_monitor    = nullptr;
     144                DeclarationWithType * decl_m_func     = nullptr;
     145                DeclarationWithType * decl_m_count    = nullptr;
     146                DeclarationWithType * decl_m_monitors = nullptr;
     147                DeclarationWithType * decl_m_isdtor   = nullptr;
    144148
    145149                static std::unique_ptr< Type > generic_func;
     
    148152                UniqueName namer_acc = "__acceptables_"s;
    149153                UniqueName namer_tim = "__timeout_"s;
    150                 UniqueName namer_ret = "__return_"s;
    151154        };
    152155
     
    164167        namespace {
    165168                Expression * makeOpIndex( DeclarationWithType * array, unsigned long index ) {
    166                         return new UntypedExpr(
     169                        return new ApplicationExpr(
    167170                                new NameExpr( "?[?]" ),
    168171                                {
     
    174177
    175178                Expression * makeOpAssign( Expression * lhs, Expression * rhs ) {
    176                         return new UntypedExpr(
     179                        return new ApplicationExpr(
    177180                                        new NameExpr( "?=?" ),
    178181                                        { lhs, rhs }
     
    180183                }
    181184
    182                 Expression * makeOpMember( Expression * sue, const std::string & mem ) {
    183                         return new UntypedMemberExpr( new NameExpr( mem ), sue );
    184                 }
    185 
    186                 Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, const std::string & member, Expression * value, const SymTab::Indexer & indexer ) {
    187                         std::unique_ptr< Expression > expr( makeOpAssign(
    188                                 makeOpMember(
    189                                         makeOpIndex(
    190                                                 object,
    191                                                 index
     185                Expression * makeOpMember( Expression * sue, DeclarationWithType * mem ) {
     186                        return new MemberExpr( mem, sue );
     187                }
     188
     189                Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, DeclarationWithType * member, Expression * value ) {
     190                        return new ExprStmt(
     191                                noLabels,
     192                                makeOpAssign(
     193                                        makeOpMember(
     194                                                makeOpIndex(
     195                                                        object,
     196                                                        index
     197                                                ),
     198                                                member
    192199                                        ),
    193                                         member
    194                                 ),
    195                                 value
    196                         ) );
    197 
    198                         return new ExprStmt( noLabels, ResolvExpr::findVoidExpression( expr.get(), indexer ) );
     200                                        value
     201                                )
     202                        );
    199203                }
    200204
     
    204208                        return new ConstantExpr( Constant::from_bool( ifnull ) );
    205209                }
    206 
    207                 VariableExpr * extractVariable( Expression * func ) {
    208                         if( VariableExpr * var = dynamic_cast< VariableExpr * >( func ) ) {
    209                                 return var;
    210                         }
    211 
    212                         CastExpr * cast = strict_dynamic_cast< CastExpr * >( func );
    213                         return strict_dynamic_cast< VariableExpr * >( cast->arg );
    214                 }
    215 
    216                 Expression * betterIsDtor( Expression * func ) {
    217                         VariableExpr * typed_func = extractVariable( func );
    218                         bool is_dtor = InitTweak::isDestructor( typed_func->var );
    219                         return new ConstantExpr( Constant::from_bool( is_dtor ) );
    220                 }
    221210        };
    222211
     
    227216
    228217        void GenerateWaitForPass::premutate( FunctionDecl * decl) {
    229                 if( decl->name != "__waitfor_internal" ) return;
     218                if( decl->name != "__accept_internal" ) return;
    230219
    231220                decl_waitfor = decl;
     
    238227                        assert( !decl_acceptable );
    239228                        decl_acceptable = decl;
     229                        for( Declaration * field : decl_acceptable->members ) {
     230                                     if( field->name == "func"    ) decl_m_func     = strict_dynamic_cast< DeclarationWithType * >( field );
     231                                else if( field->name == "count"   ) decl_m_count    = strict_dynamic_cast< DeclarationWithType * >( field );
     232                                else if( field->name == "monitor" ) decl_m_monitors = strict_dynamic_cast< DeclarationWithType * >( field );
     233                                else if( field->name == "is_dtor" ) decl_m_isdtor   = strict_dynamic_cast< DeclarationWithType * >( field );
     234                        }
     235
    240236                }
    241237                else if( decl->name == "monitor_desc" ) {
     
    246242
    247243        Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) {
     244                return waitfor;
     245
    248246                if( !decl_monitor || !decl_acceptable ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
    249247
     
    267265                );
    268266
    269                 Expression * result = call( waitfor->clauses.size(), acceptables, timeout, stmt );
    270 
    271                 choose( waitfor, result, stmt );
     267                // Expression * result  = call( acceptables, timeout, orelse, stmt );
     268
     269                // choose( waitfor, result );
    272270
    273271                return stmt;
     
    276274        ObjectDecl * GenerateWaitForPass::declare( unsigned long count, CompoundStmt * stmt )
    277275        {
    278                 ObjectDecl * acceptables = ObjectDecl::newObject(
     276                ObjectDecl * acceptables = new ObjectDecl(
    279277                        namer_acc.newName(),
     278                        noStorage,
     279                        LinkageSpec::Cforall,
     280                        nullptr,
    280281                        new ArrayType(
    281282                                noQualifiers,
     
    298299        ObjectDecl * GenerateWaitForPass::declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt ) {
    299300
    300                 ObjectDecl * mon = ObjectDecl::newObject(
     301                ObjectDecl * mon = new ObjectDecl(
    301302                        namer_mon.newName(),
     303                        noStorage,
     304                        LinkageSpec::Cforall,
     305                        nullptr,
    302306                        new ArrayType(
    303307                                noQualifiers,
     
    326330                ObjectDecl * monitors = declMon( clause, stmt );
    327331
    328                 Type * fptr_t = new PointerType( noQualifiers, new FunctionType( noQualifiers, true ) );
    329 
    330                 Expression * is_dtor = betterIsDtor( clause.target.function );
    331332                CompoundStmt * compound = new CompoundStmt( noLabels );
    332                 compound->push_back( makeAccStatement( acceptables, index, "func"    , new CastExpr( clause.target.function, fptr_t )                            , indexer ) );
    333                 compound->push_back( makeAccStatement( acceptables, index, "count"   , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), indexer ) );
    334                 compound->push_back( makeAccStatement( acceptables, index, "monitors", new VariableExpr( monitors )                                              , indexer ) );
    335                 compound->push_back( makeAccStatement( acceptables, index, "is_dtor" , is_dtor                                                                   , indexer ) );
     333                compound->push_back( makeAccStatement( acceptables, index, decl_m_func    , clause.target.function ) );
     334                compound->push_back( makeAccStatement( acceptables, index, decl_m_count   , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ) ) );
     335                compound->push_back( makeAccStatement( acceptables, index, decl_m_monitors, new VariableExpr( monitors ) ) );
     336                compound->push_back( makeAccStatement( acceptables, index, decl_m_isdtor  , new ConstantExpr( Constant::from_bool( true ) ) ) );
    336337
    337338                stmt->push_back( new IfStmt(
     
    354355                CompoundStmt * stmt
    355356        ) {
    356                 ObjectDecl * timeout = ObjectDecl::newObject(
     357                ObjectDecl * timeout = new ObjectDecl(
    357358                        namer_tim.newName(),
     359                        noStorage,
     360                        LinkageSpec::Cforall,
     361                        nullptr,
    358362                        new BasicType(
    359363                                noQualifiers,
     
    370374                        stmt->push_back( new IfStmt(
    371375                                noLabels,
    372                                 safeCond( time_cond ),
     376                                safeCond( else_cond ),
    373377                                new ExprStmt(
    374378                                        noLabels,
     
    403407                return new VariableExpr( timeout );
    404408        }
    405 
    406         Expression * GenerateWaitForPass::call(
    407                 size_t count,
    408                 ObjectDecl * acceptables,
    409                 Expression * timeout,
    410                 CompoundStmt * stmt
    411         ) {
    412                 ObjectDecl * decl = ObjectDecl::newObject(
    413                         namer_ret.newName(),
    414                         new BasicType(
    415                                 noQualifiers,
    416                                 BasicType::LongLongUnsignedInt
    417                         ),
    418                         new SingleInit(
    419                                 new UntypedExpr(
    420                                         VariableExpr::functionPointer( decl_waitfor ),
    421                                         {
    422                                                 new ConstantExpr( Constant::from_ulong( count ) ),
    423                                                 new VariableExpr( acceptables ),
    424                                                 timeout
    425                                         }
    426                                 )
    427                         )
    428                 );
    429 
    430                 stmt->push_back( new DeclStmt( noLabels, decl ) );
    431 
    432                 return new VariableExpr( decl );
    433         }
    434 
    435         void GenerateWaitForPass::choose(
    436                 WaitForStmt * waitfor,
    437                 Expression  * result,
    438                 CompoundStmt * stmt
    439         ) {
    440                 SwitchStmt * swtch = new SwitchStmt(
    441                         noLabels,
    442                         result,
    443                         std::list<Statement *>()
    444                 );
    445 
    446                 unsigned long i = 0;
    447                 for( auto & clause : waitfor->clauses ) {
    448                         swtch->statements.push_back(
    449                                 new CaseStmt(
    450                                         noLabels,
    451                                         new ConstantExpr( Constant::from_ulong( i++ ) ),
    452                                         {
    453                                                 clause.statement,
    454                                                 new BranchStmt(
    455                                                         noLabels,
    456                                                         "",
    457                                                         BranchStmt::Break
    458                                                 )
    459                                         }
    460                                 )
    461                         );
    462                 }
    463 
    464                 if(waitfor->timeout.statement) {
    465                         swtch->statements.push_back(
    466                                 new CaseStmt(
    467                                         noLabels,
    468                                         new ConstantExpr( Constant::from_ulong( i++ ) ),
    469                                         {
    470                                                 waitfor->timeout.statement,
    471                                                 new BranchStmt(
    472                                                         noLabels,
    473                                                         "",
    474                                                         BranchStmt::Break
    475                                                 )
    476                                         }
    477                                 )
    478                         );
    479                 }
    480 
    481                 if(waitfor->orelse.statement) {
    482                         swtch->statements.push_back(
    483                                 new CaseStmt(
    484                                         noLabels,
    485                                         new ConstantExpr( Constant::from_ulong( i++ ) ),
    486                                         {
    487                                                 waitfor->orelse.statement,
    488                                                 new BranchStmt(
    489                                                         noLabels,
    490                                                         "",
    491                                                         BranchStmt::Break
    492                                                 )
    493                                         }
    494                                 )
    495                         );
    496                 }
    497 
    498                 stmt->push_back( swtch );
    499         }
    500409};
    501410
Note: See TracChangeset for help on using the changeset viewer.