@@ -3022,34 +3022,79 @@ namespace {
3022
3022
void emitDirect (ArgumentSource &&arg, SILType loweredSubstArgType,
3023
3023
AbstractionPattern origParamType,
3024
3024
SILParameterInfo param) {
3025
- auto contexts = getRValueEmissionContexts (loweredSubstArgType, param);
3026
- if (arg.isRValue ()) {
3027
- emitDirect (arg.getKnownRValueLocation (), std::move (arg).asKnownRValue (),
3028
- origParamType, param, contexts.ForReabstraction );
3029
- } else {
3030
- Expr *e = std::move (arg).asKnownExpr ();
3031
- emitDirect (e, SGF.emitRValue (e, contexts.ForEmission ),
3032
- origParamType, param, contexts.ForReabstraction );
3033
- }
3034
- }
3035
-
3036
- void emitDirect (SILLocation loc, RValue &&arg,
3037
- AbstractionPattern origParamType,
3038
- SILParameterInfo param, SGFContext ctxt) {
3039
- auto value = std::move (arg).getScalarValue ();
3025
+ ManagedValue value;
3026
+
3040
3027
switch (getSILFunctionLanguage (Rep)) {
3041
3028
case SILFunctionLanguage::Swift:
3042
- value = SGF. emitSubstToOrigValue (loc, value, origParamType ,
3043
- arg. getType (), ctxt );
3029
+ value = emitSubstToOrigArgument ( std::move (arg), loweredSubstArgType ,
3030
+ origParamType, param );
3044
3031
break ;
3045
3032
case SILFunctionLanguage::C:
3046
- value = SGF. emitNativeToBridgedValue (loc, value, Rep ,
3047
- param. getType () );
3033
+ value = emitNativeToBridgedArgument ( std::move (arg), loweredSubstArgType ,
3034
+ origParamType, param);
3048
3035
break ;
3049
3036
}
3050
3037
Args.push_back (value);
3051
3038
}
3052
-
3039
+
3040
+ ManagedValue emitSubstToOrigArgument (ArgumentSource &&arg,
3041
+ SILType loweredSubstArgType,
3042
+ AbstractionPattern origParamType,
3043
+ SILParameterInfo param) {
3044
+ // TODO: We should take the opportunity to peephole certain abstraction
3045
+ // changes here, for instance, directly emitting a closure literal at the
3046
+ // callee's expected abstraction level instead of emitting it maximally
3047
+ // substituted and thunking.
3048
+ auto emitted = emitArgumentFromSource (std::move (arg), loweredSubstArgType,
3049
+ origParamType, param);
3050
+ return SGF.emitSubstToOrigValue (emitted.loc ,
3051
+ std::move (emitted.value ).getScalarValue (),
3052
+ origParamType, emitted.value .getType (),
3053
+ emitted.contextForReabstraction );
3054
+ }
3055
+
3056
+ ManagedValue emitNativeToBridgedArgument (ArgumentSource &&arg,
3057
+ SILType loweredSubstArgType,
3058
+ AbstractionPattern origParamType,
3059
+ SILParameterInfo param) {
3060
+ // TODO: We should take the opportunity to peephole certain sequences
3061
+ // here. For instance, when going from concrete type -> Any -> id, we
3062
+ // can skip the intermediate 'Any' boxing and directly bridge the concrete
3063
+ // type to its object representation. Similarly, when bridging from
3064
+ // NSFoo -> Foo -> NSFoo, we should elide the bridge altogether and pass
3065
+ // the original object.
3066
+ auto emitted = emitArgumentFromSource (std::move (arg), loweredSubstArgType,
3067
+ origParamType, param);
3068
+
3069
+ return SGF.emitNativeToBridgedValue (emitted.loc ,
3070
+ std::move (emitted.value ).getScalarValue (),
3071
+ Rep, param.getType ());
3072
+
3073
+ }
3074
+
3075
+ struct EmittedArgument {
3076
+ SILLocation loc;
3077
+ RValue value;
3078
+ SGFContext contextForReabstraction;
3079
+ };
3080
+ EmittedArgument emitArgumentFromSource (ArgumentSource &&arg,
3081
+ SILType loweredSubstArgType,
3082
+ AbstractionPattern origParamType,
3083
+ SILParameterInfo param) {
3084
+ auto contexts = getRValueEmissionContexts (loweredSubstArgType, param);
3085
+ Optional<SILLocation> loc;
3086
+ RValue rv;
3087
+ if (arg.isRValue ()) {
3088
+ loc = arg.getKnownRValueLocation ();
3089
+ rv = std::move (arg).asKnownRValue ();
3090
+ } else {
3091
+ Expr *e = std::move (arg).asKnownExpr ();
3092
+ loc = e;
3093
+ rv = SGF.emitRValue (e, contexts.ForEmission );
3094
+ }
3095
+ return {*loc, std::move (rv), contexts.ForReabstraction };
3096
+ }
3097
+
3053
3098
void maybeEmitForeignErrorArgument () {
3054
3099
if (!ForeignError ||
3055
3100
ForeignError->getErrorParameterIndex () != Args.size ())
0 commit comments