} // func InvokeMemberExpressionDynamic private static Expression EnsureInvokeResult(Scope scope, Token tStart, Expression expr, InvokeResult result, Expression instance, string memberName) { switch (result) { case InvokeResult.LuaResult: if (expr.Type == typeof(object)) { return(ConvertExpression(scope.Runtime, tStart, expr, typeof(LuaResult))); } else { return(MemberGetSandbox(scope, expr, instance, memberName)); } case InvokeResult.Object: if (LuaEmit.IsDynamicType(expr.Type)) { return(MemberGetSandbox(scope, DynamicExpression.Dynamic(scope.Runtime.GetConvertBinder(typeof(object)), typeof(object), ConvertExpression(scope.Runtime, tStart, expr, typeof(object))), instance, memberName)); } else { return(MemberGetSandbox(scope, expr, instance, memberName)); } default: return(MemberGetSandbox(scope, expr, instance, memberName)); } } // func EnsureInvokeResult
} // func InvokeExpression private static Expression InvokeMemberExpression(Scope scope, Token tStart, Expression instance, string sMember, InvokeResult result, ArgumentsList arguments) { if (LuaEmit.IsDynamicType(instance.Type)) { return(EnsureInvokeResult(scope, tStart, DynamicExpression.Dynamic(scope.Runtime.GetInvokeMemberBinder(sMember, arguments.CallInfo), typeof(object), new Expression[] { ConvertExpression(scope.Runtime, tStart, instance, typeof(object)) }.Concat( from c in arguments.Expressions select Lua.EnsureType(c, typeof(object)) ).ToArray() ), result, instance, sMember )); } else { // look up the method MethodInfo method = LuaEmit.FindMethod( LuaType.GetType(instance.Type).GetInstanceMethods(sMember, false), arguments.CallInfo, arguments.Expressions, getExpressionTypeFunction, true); if (method != null) { return(EnsureInvokeResult(scope, tStart, SafeExpression(() => InvokeMemberExpressionBind(method, scope.Runtime, instance, arguments), tStart), result, instance, sMember)); } else { return(InvokeMemberExpressionDynamic(scope, tStart, instance, sMember, result, arguments)); } } } // func InvokeMemberExpression
private static Expression MemberSetExpressionCore(Lua lua, Token tokenStart, Expression instance, string memberName, Expression set) { if (LuaEmit.IsDynamicType(instance.Type)) // first call the dynamic interface { return(DynamicExpression.Dynamic(lua.GetSetMemberBinder(memberName), typeof(object), ConvertObjectExpression(lua, tokenStart, instance, true), ConvertObjectExpression(lua, tokenStart, set, true) )); } else { Expression result; switch (LuaEmit.TrySetMember(instance, instance.Type, memberName, false, (setType) => ConvertExpression(lua, tokenStart, set, setType), out result)) { case LuaTrySetMemberReturn.None: throw ParseError(tokenStart, LuaEmitException.GetMessageText(LuaEmitException.MemberNotFound, instance.Type.Name, memberName)); case LuaTrySetMemberReturn.NotWritable: throw ParseError(tokenStart, LuaEmitException.GetMessageText(LuaEmitException.CanNotWriteMember, instance.Type.Name, memberName)); case LuaTrySetMemberReturn.ValidExpression: return(result); default: throw new ArgumentException("Internal return type of TrySetMember"); } } } // func MemberSetExpressionCore
} // func SafeExpression private static Expression ConvertObjectExpression(Lua runtime, Token tStart, Expression expr, bool lConvertToObject = false) { if (expr.Type == typeof(LuaResult)) { return(GetResultExpression(runtime, tStart, expr, 0)); } else if (expr.Type == typeof(object) && expr.NodeType == ExpressionType.Dynamic) { DynamicExpression exprDynamic = (DynamicExpression)expr; if (exprDynamic.Binder is InvokeBinder || exprDynamic.Binder is InvokeMemberBinder) { return(DynamicExpression.Dynamic(runtime.GetConvertBinder(typeof(object)), typeof(object), expr)); } else if (lConvertToObject) { return(Lua.EnsureType(expr, typeof(object))); } else { return(expr); } } else if (lConvertToObject) { return(Lua.EnsureType(expr, typeof(object))); } else { return(expr); } } // func ConvertObjectExpression
/// <summary> /// Used for conversions to bool /// </summary> private static Expression /*!*/ GetConvertByLengthBody(PythonContext /*!*/ state, Expression /*!*/ call) { Assert.NotNull(state, call); Expression callAsInt = call; if (call.Type != typeof(int)) { callAsInt = DynamicExpression.Dynamic( state.Convert(typeof(int), ConversionResultKind.ExplicitCast), typeof(int), call ); } var res = Expression.Parameter(typeof(int)); return(Ast.Block( new[] { res }, Ast.Assign(res, callAsInt), Ast.IfThen(Ast.LessThan(res, Ast.Constant(0)), Ast.Throw( Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.ValueError)), Ast.Constant("__len__() should return >= 0"), Ast.NewArrayInit(typeof(object)) ) ) ), Ast.NotEqual(res, Ast.Constant(0)) )); }
} // func MemberGetSandbox private static Expression MemberGetExpressionCore(Lua lua, Token tokenStart, Expression instance, string memberName) { // if this is a dynamic type, let the type deside what is to do if (LuaEmit.IsDynamicType(instance.Type)) { return(DynamicExpression.Dynamic(lua.GetGetMemberBinder(memberName), typeof(object), ConvertObjectExpression(lua, tokenStart, instance, true))); } else { Expression result; switch (LuaEmit.TryGetMember(instance, instance.Type, memberName, false, out result)) { case LuaTryGetMemberReturn.None: throw ParseError(tokenStart, LuaEmitException.GetMessageText(LuaEmitException.MemberNotFound, instance.Type.Name, memberName)); case LuaTryGetMemberReturn.NotReadable: throw ParseError(tokenStart, LuaEmitException.GetMessageText(LuaEmitException.CanNotReadMember, instance.Type.Name, memberName)); case LuaTryGetMemberReturn.ValidExpression: return(result); default: throw new ArgumentException("Internal return type of TryGetMember"); } } } // func MemberGetExpressionCore
protected override void AddMetaGetAttribute(PythonType metaType, PythonTypeSlot pts) { EnsureTmp(); // implementation similar to PythonTypeSlot.MakeGetExpression() Expression getExpr = Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.SlotTryGetBoundValue)), _codeContext, AstUtils.Constant(pts, typeof(PythonTypeSlot)), Expression, AstUtils.Constant(metaType), _tmp ); DynamicExpression invokeExpr = DynamicExpression.Dynamic( _state.InvokeOne, typeof(object), _codeContext, _tmp, AstUtils.Constant(GetGetMemberName(_member)) ); if (!pts.GetAlwaysSucceeds) { _cb.AddCondition(getExpr, invokeExpr); } else { _cb.FinishCondition(Ast.Block(getExpr, invokeExpr)); } }
public override Expression GetDynamicConversion(Expression value, Type type) { return(DynamicExpression.Dynamic( Binder.Context.Convert(type, ConversionResultKind.ExplicitCast), type, value)); }
public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) { return(new DynamicMetaObject( DynamicExpression.Dynamic(new MyInvokeBinder(CallInfo), typeof(object), DynamicUtils.GetExpressions(ArrayUtils.Insert(target, args))), target.Restrictions.Merge(BindingRestrictions.Combine(args)) )); }
private DynamicMetaObject GetTargetDynamicCall(CallSiteBinder binder, Type typeReturn, Expression[] exprs) { return(new DynamicMetaObject( DynamicExpression.Dynamic(binder, typeReturn, exprs), Restrictions.Merge(BindingRestrictions.GetTypeRestriction(Expression, typeof(LuaResult))) )); } // func GetTargetDynamicCall
/// <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( DynamicExpression.Dynamic( _context.CompatInvoke(callInfo), typeof(object), metaArgs.ToArray() ), restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target.Expression, target.GetLimitType())) ), args, new ValidationInfo(test) )); }
} // func IndexSetExpression private static Expression InvokeExpression(Scope scope, Token tStart, Expression instance, InvokeResult result, ArgumentsList arguments, bool lParse) { MethodInfo mi; ConstantExpression constInstance = instance as ConstantExpression; LuaType t; if (constInstance != null && (t = constInstance.Value as LuaType) != null && t.Type != null) // we have a type, bind the ctor { var type = t.Type; var typeInfo = type.GetTypeInfo(); var ci = typeInfo.IsValueType && arguments.Count == 0 ? null : LuaEmit.FindMember(typeInfo.DeclaredConstructors.Where(c => c.IsPublic), arguments.CallInfo, arguments.Expressions, getExpressionTypeFunction, false); if (ci == null && !typeInfo.IsValueType) { throw ParseError(tStart, String.Format(Properties.Resources.rsMemberNotResolved, type.Name, "ctor")); } return(SafeExpression(() => LuaEmit.BindParameter(scope.Runtime, args => ci == null ? Expression.New(type) : Expression.New(ci, args), ci == null ? new ParameterInfo[0] : ci.GetParameters(), arguments.CallInfo, arguments.Expressions, getExpressionFunction, getExpressionTypeFunction, true), tStart)); } else if (LuaEmit.IsDynamicType(instance.Type)) { // fallback is a dynamic call return(EnsureInvokeResult(scope, tStart, DynamicExpression.Dynamic(scope.Runtime.GetInvokeBinder(arguments.CallInfo), typeof(object), new Expression[] { ConvertExpression(scope.Runtime, tStart, instance, typeof(object)) }.Concat( from c in arguments.Expressions select Lua.EnsureType(c, typeof(object)) ) ), result, instance, null )); } else if (typeof(Delegate).GetTypeInfo().IsAssignableFrom(instance.Type.GetTypeInfo()) && // test if the type is assignable from delegate (mi = instance.Type.GetRuntimeMethods().Where(c => !c.IsStatic && c.IsPublic && c.Name == "Invoke").FirstOrDefault()) != null) // Search the Invoke method for the arguments { return(EnsureInvokeResult(scope, tStart, SafeExpression(() => LuaEmit.BindParameter <Expression>( scope.Runtime, args => Expression.Invoke(instance, args), mi.GetParameters(), arguments.CallInfo, arguments.Expressions, getExpressionFunction, getExpressionTypeFunction, true), tStart), result, instance, null )); } else { throw ParseError(tStart, LuaEmitException.GetMessageText(LuaEmitException.InvokeNoDelegate, instance.Type.Name)); } } // func InvokeExpression
/// <summary> /// Backwards compatible Convert for the old sites that need to flow CodeContext /// </summary> public static Expression /*!*/ Convert(Expression /*!*/ codeContext, PythonContext /*!*/ binder, Type /*!*/ type, ConversionResultKind resultKind, Expression /*!*/ target) { return(DynamicExpression.Dynamic( binder.Convert(type, resultKind), type, target )); }
private DynamicMetaObject /*!*/ MakeCallRule(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject[] args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass Invoke w/ " + args.Length + " args"); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass Invoke"); CallSignature signature = BindingHelpers.GetCallSignature(call); // TODO: If we know __init__ wasn't present we could construct the OldInstance directly. Expression[] exprArgs = new Expression[args.Length]; for (int i = 0; i < args.Length; i++) { exprArgs[i] = args[i].Expression; } ParameterExpression init = Ast.Variable(typeof(object), "init"); ParameterExpression instTmp = Ast.Variable(typeof(object), "inst"); DynamicMetaObject self = Restrict(typeof(OldClass)); return(new DynamicMetaObject( Ast.Block( new ParameterExpression[] { init, instTmp }, Ast.Assign( instTmp, Ast.New( typeof(OldInstance).GetConstructor(new Type[] { typeof(CodeContext), typeof(OldClass) }), codeContext, self.Expression ) ), Ast.Condition( Expression.Not( Expression.TypeIs( Expression.Assign( init, Ast.Call( typeof(PythonOps).GetMethod("OldClassTryLookupInit"), self.Expression, instTmp ) ), typeof(OperationFailed) ) ), DynamicExpression.Dynamic( PythonContext.GetPythonContext(call).Invoke( signature ), typeof(object), ArrayUtils.Insert <Expression>(codeContext, init, exprArgs) ), NoInitCheckNoArgs(signature, self, args) ), instTmp ), self.Restrictions.Merge(BindingRestrictions.Combine(args)) )); }
private DynamicMetaObject InvokeWorker(DynamicMetaObjectBinder /*!*/ callAction, DynamicMetaObject /*!*/[] args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Method Invoke " + args.Length); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "Method"); CallSignature signature = BindingHelpers.GetCallSignature(callAction); DynamicMetaObject self = Restrict(typeof(Method)); BindingRestrictions restrictions = self.Restrictions; // restrict to non-null self (Method is immutable so this is an invariant test) restrictions = restrictions.Merge( BindingRestrictions.GetExpressionRestriction( Ast.NotEqual( GetSelfExpression(self), AstUtils.Constant(null) ) ) ); DynamicMetaObject[] newArgs = ArrayUtils.Insert(GetMetaFunction(self), GetMetaSelf(self), args); var newSig = new CallSignature(ArrayUtils.Insert(new Argument(ArgumentType.Simple), signature.GetArgumentInfos())); var call = new DynamicMetaObject( DynamicExpression.Dynamic( PythonContext.GetPythonContext(callAction).Invoke( newSig ).GetLightExceptionBinder(callAction.SupportsLightThrow()), typeof(object), ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(newArgs)) ), BindingRestrictions.Empty ); /* * call = func.Invoke( * new CallBinder( * PythonContext.GetBinderState(callAction), * newSig * ), * newArgs * );*/ if (call.HasValue) { return(new DynamicMetaObject( call.Expression, restrictions.Merge(call.Restrictions), call.Value )); } else { return(new DynamicMetaObject( call.Expression, restrictions.Merge(call.Restrictions) )); } }
} // func InvokeMemberExpressionBind private static Expression InvokeMemberExpressionDynamic(Scope scope, Token tStart, Expression instance, string sMember, InvokeResult result, ArgumentsList arguments) { return(EnsureInvokeResult(scope, tStart, DynamicExpression.Dynamic(scope.Runtime.GetInvokeMemberBinder(sMember, arguments.CallInfo), typeof(object), new Expression[] { ConvertExpression(scope.Runtime, tStart, instance, typeof(object)) }.Concat(from a in arguments.Expressions select Lua.EnsureType(a, typeof(object))).ToArray() ), result, instance, sMember )); } // func InvokeMemberExpressionDynamic
public static Expression CompileGetMember(Expression target, string clientExpr) { var binder = DynamicBinder.GetMember(CSharpBinderFlags.None, clientExpr, typeof(DynamicBindingHelper), EMPTY_ARGUMENT_INFO); return(Expression.Call( typeof(Utils).GetMethod(nameof(Utils.UnwrapNewtonsoftValue)), DynamicExpression.Dynamic(binder, typeof(object), target) )); }
public static Expression /*!*/ Get(Expression /*!*/ codeContext, PythonContext /*!*/ binder, Type /*!*/ resultType, string /*!*/ name, Expression /*!*/ target) { return(DynamicExpression.Dynamic( binder.GetMember(name), resultType, target, codeContext )); }
public override Expression Reduce() { // we just reduce to a simple DynamicExpression return(DynamicExpression.Dynamic( new ComboBinder(Binders), Type, Inputs )); }
public static Expression /*!*/ Invoke(Expression codeContext, PythonContext /*!*/ binder, Type /*!*/ resultType, CallSignature signature, params Expression /*!*/[] /*!*/ args) { return(DynamicExpression.Dynamic( binder.Invoke( signature ), resultType, ArrayUtils.Insert(codeContext, args) )); }
public static SlotOrFunction /*!*/ GetSlotOrFunction(PythonContext /*!*/ state, string op, params DynamicMetaObject[] types) { PythonTypeSlot slot; SlotOrFunction res; if (TryGetBinder(state, types, op, null, out res)) { if (res != SlotOrFunction.Empty) { return(res); } } else if (MetaUserObject.GetPythonType(types[0]).TryResolveSlot(state.SharedContext, op, out slot)) { ParameterExpression tmp = Ast.Variable(typeof(object), "slotVal"); Expression[] args = new Expression[types.Length - 1]; for (int i = 1; i < types.Length; i++) { args[i - 1] = types[i].Expression; } return(new SlotOrFunction( new DynamicMetaObject( Ast.Block( new ParameterExpression[] { tmp }, MetaPythonObject.MakeTryGetTypeMember( state, slot, tmp, types[0].Expression, Ast.Call( typeof(DynamicHelpers).GetMethod("GetPythonType"), types[0].Expression ) ), DynamicExpression.Dynamic( state.Invoke( new CallSignature(args.Length) ), typeof(object), ArrayUtils.Insert <Expression>( AstUtils.Constant(state.SharedContext), tmp, args ) ) ), BindingRestrictions.Combine(types).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(types[0].Expression, types[0].GetLimitType())) ), slot )); } return(SlotOrFunction.Empty); }
public static Expression CompileGetMember(Expression target, string clientExpr) { if(EMPTY_ARGUMENT_INFO == null) EMPTY_ARGUMENT_INFO = new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }; var binder = DynamicBinder.GetMember(CSharpBinderFlags.None, clientExpr, typeof(DynamicBindingHelper), EMPTY_ARGUMENT_INFO); return Expression.Call( typeof(Utils).GetMethod(nameof(Utils.UnwrapNewtonsoftValue)), DynamicExpression.Dynamic(binder, typeof(object), target) ); }
private DynamicMetaObject GetForeignObject(DynamicMetaObject self) { return(new DynamicMetaObject( DynamicExpression.Dynamic( _context.CompatGetMember(Name, IsNoThrow), typeof(object), self.Expression ), self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, self.GetLimitType())) )); }
private DynamicMetaObject MyDefer(DynamicMetaObject self) { return(new DynamicMetaObject( DynamicExpression.Dynamic( this, ReturnType, self.Expression ), self.Restrictions )); }
public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) { return(new DynamicMetaObject( DynamicExpression.Dynamic( _context.CreateInvokeBinder(CallInfo), typeof(object), GetArgs(target, args) ), target.Restrictions.Merge(BindingRestrictions.Combine(args)) )); }
public void BinaryCallSiteBinder_DynamicExpression(bool useInterpreter) { DynamicExpression expression = DynamicExpression.Dynamic( new BinaryCallSiteBinder(), typeof(object), Expression.Constant(40, typeof(object)), Expression.Constant(2, typeof(object))); Func <object> func = Expression.Lambda <Func <object> >(expression).Compile(useInterpreter); Assert.Equal("42", func().ToString()); }
private DynamicExpression MakeDynamicInitInvoke(CodeContext context, DynamicMetaObject[] args, Expression initFunc, Expression codeContext) { return(DynamicExpression.Dynamic( context.LanguageContext.Invoke(_signature), typeof(object), ArrayUtils.Insert( codeContext, initFunc, DynamicUtils.GetExpressions(args) ) )); }
static Func <dynamic, object> CompileConverter(Type targetType) { var valueParameter = Expression.Parameter(typeof(object), "value"); return(Expression.Lambda <Func <object, object> >( Expression.Convert( DynamicExpression.Dynamic( Binder.Convert(CSharpBinderFlags.ConvertExplicit, targetType, null), targetType, valueParameter ), typeof(object)), valueParameter).Compile()); }
Expression ILightExceptionAwareExpression.ReduceForLightExceptions() { if (Binder is ILightExceptionBinder binder) { var lightBinder = binder.GetLightExceptionBinder() as DynamicMetaObjectBinder; if (lightBinder != binder) { return(DynamicExpression.Dynamic( lightBinder, Type, Args)); } } return(this); }
} // func InvokeExpression private static Expression InvokeMemberExpression(Scope scope, Token tStart, Expression instance, string memberName, InvokeResult result, ArgumentsList arguments) { if (LuaEmit.IsDynamicType(instance.Type) || arguments.Expressions.Any(c => LuaEmit.IsDynamicType(c.Type))) { var dynamicArguments = new Expression[arguments.Count + 1]; // first argument is the instance dynamicArguments[0] = ConvertObjectExpression(scope.Runtime, tStart, instance, false); if (arguments.Count > 0) { // single object for (var i = 0; i < arguments.Count - 1; i++) { dynamicArguments[i + 1] = ConvertObjectExpression(scope.Runtime, tStart, arguments.Expressions[i], false); } // last argument is different if (arguments.CallInfo.ArgumentNames.Count > 0) { dynamicArguments[dynamicArguments.Length - 1] = ConvertObjectExpression(scope.Runtime, tStart, arguments.Expressions[arguments.Count - 1], false); } else { dynamicArguments[dynamicArguments.Length - 1] = Lua.EnsureType(arguments.Expressions[arguments.Count - 1], typeof(object)); } } return(EnsureInvokeResult(scope, tStart, DynamicExpression.Dynamic(scope.Runtime.GetInvokeMemberBinder(memberName, arguments.CallInfo), typeof(object), dynamicArguments), result, instance, memberName )); } else { return(EnsureInvokeResult(scope, tStart, SafeExpression(() => { Expression expr; if (!LuaEmit.TryInvokeMember <Expression>(scope.Runtime, LuaType.GetType(instance.Type), instance, arguments.CallInfo, arguments.Expressions, memberName, false, e => e, e => e.Type, true, out expr)) { throw new LuaEmitException(LuaEmitException.MemberNotFound, instance.Type, memberName); } return expr; }, tStart), result, instance, memberName )); } } // func InvokeMemberExpression