Changeset ae1b9ea for src/GenPoly


Ignore:
Timestamp:
Oct 19, 2017, 11:15:36 AM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
a365e0d
Parents:
aabc60c
git-author:
Rob Schluntz <rschlunt@…> (10/17/17 17:10:04)
git-committer:
Rob Schluntz <rschlunt@…> (10/19/17 11:15:36)
Message:

Always copy construct arguments that require boxing

Location:
src/GenPoly
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    raabc60c rae1b9ea  
    715715                void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
    716716                        assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() );
    717                         if ( isPolyType( param, exprTyVars ) ) {
    718                                 Type * newType = arg->get_result()->clone();
     717                        if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return;
     718
     719                        if ( arg->result->get_lvalue() ) {
     720                                // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations.
     721                                // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) {
     722                                //      if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){
     723                                //              // temporary hack - don't box arrays, because &arr is not the same as &arr[0]
     724                                //              return;
     725                                //      }
     726                                // }
     727                                arg =  generalizedLvalue( new AddressExpr( arg ) );
     728                                if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) {
     729                                        // silence warnings by casting boxed parameters when the actual type does not match up with the formal type.
     730                                        arg = new CastExpr( arg, param->clone() );
     731                                }
     732                        } else {
     733                                // use type computed in unification to declare boxed variables
     734                                Type * newType = param->clone();
    719735                                if ( env ) env->apply( newType );
    720                                 std::unique_ptr<Type> manager( newType );
    721                                 if ( isPolyType( newType ) ) {
    722                                         // if the argument's type is polymorphic, we don't need to box again!
    723                                         return;
    724                                 } else if ( arg->get_result()->get_lvalue() ) {
    725                                         // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations.
    726                                         // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) {
    727                                         //      if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){
    728                                         //              // temporary hack - don't box arrays, because &arr is not the same as &arr[0]
    729                                         //              return;
    730                                         //      }
    731                                         // }
    732                                         arg =  generalizedLvalue( new AddressExpr( arg ) );
    733                                         if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) {
    734                                                 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type.
    735                                                 arg = new CastExpr( arg, param->clone() );
    736                                         }
    737                                 } else {
    738                                         // use type computed in unification to declare boxed variables
    739                                         Type * newType = param->clone();
    740                                         if ( env ) env->apply( newType );
    741                                         ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 );
    742                                         newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
    743                                         stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
    744                                         UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax?
    745                                         assign->get_args().push_back( new VariableExpr( newObj ) );
    746                                         assign->get_args().push_back( arg );
    747                                         stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) );
    748                                         arg = new AddressExpr( new VariableExpr( newObj ) );
    749                                 } // if
     736                                ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 );
     737                                newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
     738                                stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
     739                                UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax?
     740                                assign->get_args().push_back( new VariableExpr( newObj ) );
     741                                assign->get_args().push_back( arg );
     742                                stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) );
     743                                arg = new AddressExpr( new VariableExpr( newObj ) );
    750744                        } // if
    751745                }
  • src/GenPoly/GenPoly.cc

    raabc60c rae1b9ea  
    432432        }
    433433
     434        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env ) {
     435                // is parameter is not polymorphic, don't need to box
     436                if ( ! isPolyType( param, exprTyVars ) ) return false;
     437                Type * newType = arg->clone();
     438                if ( env ) env->apply( newType );
     439                std::unique_ptr<Type> manager( newType );
     440                // if the argument's type is polymorphic, we don't need to box again!
     441                return ! isPolyType( newType );
     442        }
     443
     444        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env ) {
     445                FunctionType * function = getFunctionType( appExpr->function->result );
     446                assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() );
     447                TyVarMap exprTyVars( TypeDecl::Data{} );
     448                makeTyVarMap( function, exprTyVars );
     449                return needsBoxing( param, arg, exprTyVars, env );
     450        }
     451
    434452        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
    435453                // xxx - should this actually be insert?
  • src/GenPoly/GenPoly.h

    raabc60c rae1b9ea  
    8080        bool typesPolyCompatible( Type *aty, Type *bty );
    8181
     82        /// true if arg requires boxing given exprTyVars
     83        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env );
     84
     85        /// true if arg requires boxing in the call to appExpr
     86        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env );
     87
    8288        /// Adds the type variable `tyVar` to `tyVarMap`
    8389        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap );
Note: See TracChangeset for help on using the changeset viewer.