private Expression AddReturnChecks(CodeContext context, DynamicMetaObject[] args, Expression res) { PythonContext ctx = context.LanguageContext; object resType = Value.Getrestype(); if (resType != null) { // res type can be callable, a type with _check_retval_, or // it can be just be a type which doesn't require post-processing. INativeType nativeResType = resType as INativeType; object checkRetVal = null; if (nativeResType == null) { checkRetVal = resType; } else if (!PythonOps.TryGetBoundAttr(context, nativeResType, "_check_retval_", out checkRetVal)) { // we just wanted to try and get the value, don't need to do anything here. checkRetVal = null; } if (checkRetVal != null) { res = Expression.Dynamic( ctx.CompatInvoke(new CallInfo(1)), typeof(object), Expression.Constant(checkRetVal), res ); } } object errCheck = Value.Geterrcheck(); if (errCheck != null) { res = Expression.Dynamic( ctx.CompatInvoke(new CallInfo(3)), typeof(object), Expression.Constant(errCheck), res, Expression, Expression.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.MakeTuple)), Expression.NewArrayInit( typeof(object), ArrayUtils.ConvertAll(args, x => Utils.Convert(x.Expression, typeof(object))) ) ) ); } return(res); }
/// <summary> /// Creates a nested dynamic site which uses the unpacked arguments. /// </summary> internal DynamicMetaObject InvokeForeignObject(DynamicMetaObject target, DynamicMetaObject[] args) { // need to unpack any dict / list arguments... CallInfo callInfo; List <Expression> metaArgs; Expression test; BindingRestrictions restrictions; TranslateArguments(target, args, out callInfo, out metaArgs, out test, out restrictions); Debug.Assert(metaArgs.Count > 0); return(BindingHelpers.AddDynamicTestAndDefer( this, new DynamicMetaObject( Expression.Dynamic( _context.CompatInvoke(callInfo), typeof(object), metaArgs.ToArray() ), restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target.Expression, target.GetLimitType())) ), args, new ValidationInfo(test) )); }