Exemplo n.º 1
0
        internal override Expression MarshalToRef(Expression parameter)
        {
            parameter = Marshal(parameter);

            // parameter == null ? IntPtr.Zero : Marshal.GetIDispatchForObject(parameter);
            return(Expression.Condition(
                       Expression.Equal(parameter, Expression.Constant(null)),
                       Expression.Constant(IntPtr.Zero),
                       Expression.Call(
                           ComRuntimeHelpers.GetGetIDispatchForObjectMethod(),
                           parameter
                           )
                       ));
        }
        /// <summary>
        /// Create a stub for the target of the optimized lopop.
        /// </summary>
        /// <returns></returns>
        private Expression MakeIDispatchInvokeTarget()
        {
            Debug.Assert(_varEnumSelector.VariantBuilders.Length == _totalExplicitArgs);

            List <Expression> exprs = new List <Expression>();

            //
            // _dispId = ((DispCallable)this).ComMethodDesc.DispId;
            //
            exprs.Add(
                Expression.Assign(
                    DispIdVariable,
                    Expression.Property(_method, typeof(ComMethodDesc).GetProperty(nameof(ComMethodDesc.DispId)))
                    )
                );

            //
            // _dispParams.rgvararg = RuntimeHelpers.UnsafeMethods.ConvertVariantByrefToPtr(ref _paramVariants._element0)
            //
            if (_totalExplicitArgs != 0)
            {
                exprs.Add(
                    Expression.Assign(
                        Expression.Field(
                            DispParamsVariable,
                            typeof(ComTypes.DISPPARAMS).GetField(nameof(ComTypes.DISPPARAMS.rgvarg))
                            ),
                        Expression.Call(
                            typeof(UnsafeMethods).GetMethod(nameof(UnsafeMethods.ConvertVariantByrefToPtr)),
                            VariantArray.GetStructField(ParamVariantsVariable, 0)
                            )
                        )
                    );
            }

            //
            // _dispParams.cArgs = <number_of_params>;
            //
            exprs.Add(
                Expression.Assign(
                    Expression.Field(
                        DispParamsVariable,
                        typeof(ComTypes.DISPPARAMS).GetField(nameof(ComTypes.DISPPARAMS.cArgs))
                        ),
                    Expression.Constant(_totalExplicitArgs)
                    )
                );

            if (_methodDesc.IsPropertyPut)
            {
                //
                // dispParams.cNamedArgs = 1;
                // dispParams.rgdispidNamedArgs = RuntimeHelpers.UnsafeMethods.GetNamedArgsForPropertyPut()
                //
                exprs.Add(
                    Expression.Assign(
                        Expression.Field(
                            DispParamsVariable,
                            typeof(ComTypes.DISPPARAMS).GetField(nameof(ComTypes.DISPPARAMS.cNamedArgs))
                            ),
                        Expression.Constant(1)
                        )
                    );

                exprs.Add(
                    Expression.Assign(
                        PropertyPutDispIdVariable,
                        Expression.Constant(ComDispIds.DISPID_PROPERTYPUT)
                        )
                    );

                exprs.Add(
                    Expression.Assign(
                        Expression.Field(
                            DispParamsVariable,
                            typeof(ComTypes.DISPPARAMS).GetField(nameof(ComTypes.DISPPARAMS.rgdispidNamedArgs))
                            ),
                        Expression.Call(
                            typeof(UnsafeMethods).GetMethod(nameof(UnsafeMethods.ConvertInt32ByrefToPtr)),
                            PropertyPutDispIdVariable
                            )
                        )
                    );
            }
            else
            {
                //
                // _dispParams.cNamedArgs = N;
                //
                exprs.Add(
                    Expression.Assign(
                        Expression.Field(
                            DispParamsVariable,
                            typeof(ComTypes.DISPPARAMS).GetField(nameof(ComTypes.DISPPARAMS.cNamedArgs))
                            ),
                        Expression.Constant(_keywordArgNames.Length)
                        )
                    );
            }

            //
            // _dispatchObject = _dispatch
            // _dispatchPointer = Marshal.GetIDispatchForObject(_dispatchObject);
            //

            exprs.Add(Expression.Assign(DispatchObjectVariable, _dispatch));

            exprs.Add(
                Expression.Assign(
                    DispatchPointerVariable,
                    Expression.Call(
                        ComRuntimeHelpers.GetGetIDispatchForObjectMethod(),
                        DispatchObjectVariable
                        )
                    )
                );

            Expression tryStatements     = GenerateTryBlock();
            Expression finallyStatements = GenerateFinallyBlock();

            exprs.Add(Expression.TryFinally(tryStatements, finallyStatements));

            exprs.Add(ReturnValueVariable);
            var vars = new List <ParameterExpression>();

            foreach (var variant in _varEnumSelector.VariantBuilders)
            {
                if (variant.TempVariable != null)
                {
                    vars.Add(variant.TempVariable);
                }
            }
            return(Expression.Block(vars, exprs));
        }