public static MSA.DynamicExpression /*!*/ MakeCallAction(string /*!*/ name, ActionBinder /*!*/ binder, RubyCallSignature signature, params MSA.Expression[] /*!*/ args) { RubyCallAction call = RubyCallAction.Make(name, signature); switch (args.Length) { case 0: return(Ast.Dynamic(call, typeof(object), AstFactory.EmptyExpressions)); case 1: return(Ast.Dynamic(call, typeof(object), args[0])); case 2: return(Ast.Dynamic(call, typeof(object), args[0], args[1])); case 3: return(Ast.Dynamic(call, typeof(object), args[0], args[1], args[2])); case 4: return(Ast.Dynamic(call, typeof(object), args[0], args[1], args[2], args[3])); default: return(Ast.Dynamic( call, typeof(object), new ReadOnlyCollection <MSA.Expression>(args) )); } }
protected override MSA.Expression /*!*/ VisitDynamic(MSA.DynamicExpression /*!*/ node) { var callAction = node.Binder as RubyCallAction; if (callAction != null) { var args = new MSA.Expression[node.Arguments.Count]; for (int i = 0; i < args.Length; i++) { args[i] = node.Arguments[i]; } Debug.Assert(args.Length > 0); int last = args.Length - 1; args[last] = typeof(TracingRubyCallAction).GetMethod("EnterCallSite").MakeGenericMethod(args[last].Type).OpCall( args[last], AstUtils.Constant(_sourceId), AstUtils.Constant(_sites[node].Start.Index) ); return(Ast.Dynamic( new TracingRubyCallAction(callAction.MethodName, callAction.Signature), node.Type, args )); } else { return(base.VisitDynamic(node)); } }
private static Expression /*!*/ AddExtensibleSelfCheck(DynamicMetaObjectBinder /*!*/ convertToAction, Type toType, DynamicMetaObject /*!*/ self, Expression /*!*/ callExpr) { ParameterExpression tmp = Ast.Variable(callExpr.Type, "tmp"); ConversionResultKind resKind = GetResultKind(convertToAction); Type retType = (resKind == ConversionResultKind.ExplicitTry || resKind == ConversionResultKind.ImplicitTry) ? typeof(object) : toType; callExpr = Ast.Block( new ParameterExpression[] { tmp }, Ast.Block( Ast.Assign(tmp, callExpr), Ast.Condition( Ast.Equal(tmp, self.Expression), AstUtils.Convert( Ast.Property( AstUtils.Convert(self.Expression, self.GetLimitType()), self.GetLimitType().GetProperty("Value") ), retType ), Ast.Dynamic( new PythonConversionBinder( PythonContext.GetPythonContext(convertToAction), toType, GetResultKind(convertToAction) ), retType, tmp ) ) ) ); return(callExpr); }
public MSA.Expression /*!*/ MakeSuperCallAction(int lexicalScopeId) { return(Ast.Dynamic( SuperCallAction.Make(MakeCallSignature(true), lexicalScopeId), typeof(object), GetExpressions() )); }
public virtual MSAst.Expression /*!*/ Dynamic(DynamicMetaObjectBinder /*!*/ binder, Type /*!*/ retType, params MSAst.Expression /*!*/[] /*!*/ args) { Assert.NotNull(binder, retType, args); Assert.NotNullItems(args); return(Ast.Dynamic(binder, retType, args)); }
/// <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(Ast.Dynamic( binder.Convert(type, resultKind), type, target )); }
internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen) { return(Methods.MatchString.OpCall( Ast.Dynamic(ConvertToStrAction.Instance, typeof(MutableString), gen.CurrentScopeVariable, _expression.Transform(gen)), _regex.Transform(gen), gen.CurrentScopeVariable )); }
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) ) ), Ast.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 MSA.Expression /*!*/ TransformSplatType(AstGenerator /*!*/ gen) { return(Ast.Dynamic( TryConvertToArrayAction.Instance, typeof(object), gen.CurrentScopeVariable, _splatType.TransformRead(gen) )); }
public static Expression /*!*/ Get(Expression /*!*/ codeContext, PythonContext /*!*/ binder, Type /*!*/ resultType, string /*!*/ name, Expression /*!*/ target) { return(Ast.Dynamic( binder.GetMember(name), resultType, target, codeContext )); }
internal override MSA.Expression /*!*/ Transform(AstGenerator /*!*/ gen) { Assert.NotNull(gen); return(Ast.Dynamic( ConvertToProcAction.Instance, typeof(Proc), gen.CurrentScopeVariable, _expression.TransformRead(gen) )); }
private DynamicMetaObject /*!*/ InvokeWorker(DynamicMetaObjectBinder /*!*/ invoke, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass Invoke"); DynamicMetaObject self = Restrict(typeof(OldInstance)); Expression[] exprArgs = new Expression[args.Length + 1]; for (int i = 0; i < args.Length; i++) { exprArgs[i + 1] = args[i].Expression; } ParameterExpression tmp = Ast.Variable(typeof(object), "callFunc"); exprArgs[0] = tmp; return(new DynamicMetaObject( // we could get better throughput w/ a more specific rule against our current custom old class but // this favors less code generation. Ast.Block( new ParameterExpression[] { tmp }, Ast.Condition( Ast.Call( typeof(PythonOps).GetMethod("OldInstanceTryGetBoundCustomMember"), codeContext, self.Expression, AstUtils.Constant("__call__"), tmp ), Ast.Block( Utils.Try( Ast.Call(typeof(PythonOps).GetMethod("FunctionPushFrameCodeContext"), codeContext), Ast.Assign( tmp, Ast.Dynamic( PythonContext.GetPythonContext(invoke).Invoke( BindingHelpers.GetCallSignature(invoke) ), typeof(object), ArrayUtils.Insert(codeContext, exprArgs) ) ) ).Finally( Ast.Call(typeof(PythonOps).GetMethod("FunctionPopFrame")) ), tmp ), Utils.Convert( BindingHelpers.InvokeFallback(invoke, codeContext, this, args).Expression, typeof(object) ) ) ), self.Restrictions.Merge(BindingRestrictions.Combine(args)) )); }
public static Expression /*!*/ Invoke(Expression codeContext, PythonContext /*!*/ binder, Type /*!*/ resultType, CallSignature signature, params Expression /*!*/[] /*!*/ args) { return(Ast.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 ) ), Ast.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); }
// when <expr> // generates into: // RubyOps.IsTrue(<expr>) if the case has no value, otherise: // RubyOps.IsTrue(InvokeMember("===", <expr>, <value>)) private static MSA.Expression /*!*/ MakeTest(AstGenerator /*!*/ gen, MSA.Expression /*!*/ expr, MSA.Expression /*!*/ value) { if (value != null) { // InvokeMember("===", <expr>, <value>) expr = Ast.Dynamic(RubyCallAction.Make("===", RubyCallSignature.WithScope(1)), typeof(object), gen.CurrentScopeVariable, expr, value ); } return(AstFactory.IsTrue(expr)); }
public Ast ResolveForDelete(string name) { var param = Parameters.Select(x => x.ParameterVariable).FirstOrDefault(x => x != null && x.Name == name); if (param != null || _variables.TryGetValue(name, out param)) { return(Ast.Constant(0L)); } else { return(Ast.Dynamic(new ThisProxyMemberAccessBinder( LanguageContext, name, false, MemberAccessKind.Delete ), typeof(object), _context, _global)); } }
public Ast ResolveForWrite(string name, Ast value, bool direct) { var param = Parameters.Select(x => x.ParameterVariable).FirstOrDefault(x => x != null && x.Name == name); if (param != null || _variables.TryGetValue(name, out param)) { return(Ast.Assign(param, value)); } else { return(Ast.Dynamic(new ThisProxyMemberAccessBinder( LanguageContext, name, false, direct ? MemberAccessKind.Set | MemberAccessKind.Direct : MemberAccessKind.Set ), typeof(object), _context, _global, value)); } }
internal static DynamicMetaObject ConvertToIEnumerator(DynamicMetaObjectBinder /*!*/ conversion, DynamicMetaObject /*!*/ metaUserObject) { PythonType pt = MetaPythonObject.GetPythonType(metaUserObject); PythonContext state = PythonContext.GetPythonContext(conversion); CodeContext context = state.SharedContext; PythonTypeSlot pts; if (pt.TryResolveSlot(context, "__iter__", out pts)) { ParameterExpression tmp = Ast.Parameter(typeof(object), "iterVal"); return(new DynamicMetaObject( Expression.Block( new[] { tmp }, Expression.Call( typeof(PythonOps).GetMethod("CreatePythonEnumerator"), Ast.Block( MetaPythonObject.MakeTryGetTypeMember( state, pts, metaUserObject.Expression, tmp ), Ast.Dynamic( new PythonInvokeBinder( state, new CallSignature(0) ), typeof(object), AstUtils.Constant(context), tmp ) ) ) ), metaUserObject.Restrictions )); } else if (pt.TryResolveSlot(context, "__getitem__", out pts)) { return(MakeGetItemIterable(metaUserObject, state, pts, "CreateItemEnumerator")); } return(null); }
/// <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 = Ast.Dynamic( state.Convert(typeof(int), ConversionResultKind.ExplicitCast), typeof(int), call ); } return(Ast.NotEqual(callAsInt, AstUtils.Constant(0))); }
internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen) { Assert.NotNull(gen); MSA.Expression transformedBlock = _block.Transform(gen); MSA.Expression blockArgVariable = gen.CurrentScope.DefineHiddenVariable("#forloop-block", typeof(Proc)); MSA.Expression result = Ast.Dynamic(RubyCallAction.Make("each", RubyCallSignature.WithScopeAndBlock(0)), typeof(object), gen.CurrentScopeVariable, _list.TransformRead(gen), blockArgVariable ); return(gen.DebugMark(MethodCall.MakeCallWithBlockRetryable(gen, result, blockArgVariable, transformedBlock, true), "#RB: method call with a block ('for-loop')")); }
// // Traverses expressions in "parts" and concats all contiguous literal strings. // Notes: // - Instead of usign StringBuilder we place the string values that can be concatenated so far in to "literals" list and keep track // of their total length in "concatLength" and encoding in "concatEncoding". // If we reach a non-literal expression and we have some literals ready in "literals" array we do the concat and clear the list // and "concatLength" and "concatEncoding". // - "result" list contains argument expressions to the CreateMutableString* overloads. // - "opName" contains the name of the operation. This method appends suffix based on the argument types (see RubyOps.Suffix*). // private static void ConcatLiteralsAndTransformRecursive(AstGenerator /*!*/ gen, List <Expression> /*!*/ parts, List <string> /*!*/ literals, ref int concatLength, ref StringLiteralEncoding concatEncoding, List <MSA.Expression> /*!*/ result, StringBuilder /*!*/ opName) { for (int i = 0; i < parts.Count; i++) { Expression part = parts[i]; StringLiteral literal; StringConstructor ctor; if ((literal = part as StringLiteral) != null) { literals.Add(literal.Value); concatEncoding = CombineEncoding(concatEncoding, literal); concatLength += literal.Value.Length; } else if ((ctor = part as StringConstructor) != null) { ConcatLiteralsAndTransformRecursive(gen, ctor.Parts, literals, ref concatLength, ref concatEncoding, result, opName); } else { if (literals.Count > 0) { result.Add(Ast.Constant(Concat(literals, concatLength))); opName.Append(OpSuffix(gen, concatEncoding)); concatLength = 0; concatEncoding = StringLiteralEncoding.Ascii; literals.Clear(); } result.Add( Ast.Dynamic( ConvertToSAction.Instance, typeof(MutableString), gen.CurrentScopeVariable, part.TransformRead(gen) ) ); opName.Append(RubyOps.SuffixMutable); } } }
internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen) { switch (_kind) { case StringKind.Mutable: return(TransformConcatentation(gen, _parts, Methods.CreateMutableString, null)); case StringKind.Immutable: return(TransformConcatentation(gen, _parts, Methods.CreateSymbol, null)); case StringKind.Command: return(Ast.Dynamic(RubyCallAction.Make("`", new RubyCallSignature(1, RubyCallFlags.HasScope | RubyCallFlags.HasImplicitSelf)), typeof(object), gen.CurrentScopeVariable, gen.CurrentSelfVariable, TransformConcatentation(gen, _parts, Methods.CreateMutableString, null) )); } throw Assert.Unreachable; }
protected DynamicMetaObject /*!*/ MakeDefaultNew(DefaultBinder /*!*/ binder, Expression /*!*/ function) { // calling theType.__new__(theType, args) List <Expression> args = new List <Expression>(); args.Add(CodeContext); args.Add(function); AppendNewArgs(args); return(new DynamicMetaObject( Ast.Dynamic( PythonContext.Invoke( GetDynamicNewSignature() ), typeof(object), args.ToArray() ), Arguments.Self.Restrictions )); }
protected override void AddMetaGetAttribute(PythonType metaType, PythonTypeSlot pts) { EnsureTmp(); _cb.AddCondition( Ast.Call( typeof(PythonOps).GetMethod("SlotTryGetBoundValue"), _codeContext, AstUtils.Constant(pts, typeof(PythonTypeSlot)), Expression, AstUtils.Constant(metaType), _tmp ), Ast.Dynamic( _state.InvokeOne, typeof(object), _codeContext, _tmp, AstUtils.Constant(GetGetMemberName(_member)) ) ); }
private DynamicMetaObject /*!*/ MakeSetMember(SetMemberBinder /*!*/ member, DynamicMetaObject /*!*/ value) { PythonContext state = PythonContext.GetPythonContext(member); DynamicMetaObject self = Restrict(Value.GetType()); if (Value.GetType() != typeof(PythonType) && DynamicHelpers.GetPythonType(Value).IsSystemType) { // built-in subclass of .NET type. Usually __setattr__ is handled by MetaUserObject // but we can have a built-in subtype that's not a user type. PythonTypeSlot pts; if (Value.TryGetCustomSetAttr(state.SharedContext, out pts)) { Debug.Assert(pts.GetAlwaysSucceeds); ParameterExpression tmp = Ast.Variable(typeof(object), "boundVal"); return(BindingHelpers.AddDynamicTestAndDefer( member, new DynamicMetaObject( Ast.Block( new[] { tmp }, Ast.Dynamic( state.Invoke(new CallSignature(2)), typeof(object), AstUtils.Constant(state.SharedContext), Ast.Block( Ast.Call( typeof(PythonOps).GetMethod("SlotTryGetValue"), AstUtils.Constant(state.SharedContext), AstUtils.Convert(AstUtils.WeakConstant(pts), typeof(PythonTypeSlot)), AstUtils.Convert(Expression, typeof(object)), AstUtils.Convert(AstUtils.WeakConstant(DynamicHelpers.GetPythonType(Value)), typeof(PythonType)), tmp ), tmp ), Ast.Constant(member.Name), value.Expression ) ), self.Restrictions ), new DynamicMetaObject[] { this, value }, TestUserType() )); } } return(BindingHelpers.AddDynamicTestAndDefer( member, new DynamicMetaObject( Ast.Call( typeof(PythonOps).GetMethod("PythonTypeSetCustomMember"), AstUtils.Constant(PythonContext.GetPythonContext(member).SharedContext), self.Expression, AstUtils.Constant(member.Name), AstUtils.Convert( value.Expression, typeof(object) ) ), self.Restrictions.Merge(value.Restrictions) ), new DynamicMetaObject[] { this, value }, TestUserType() )); }
private DynamicMetaObject /*!*/ MakeConvertRuleForCall(DynamicMetaObjectBinder /*!*/ convertToAction, Type toType, DynamicMetaObject /*!*/ self, string name, string returner, Func <DynamicMetaObject> fallback, Func <Expression, Expression> resultConverter) { PythonType pt = ((IPythonObject)self.Value).PythonType; PythonTypeSlot pts; CodeContext context = PythonContext.GetPythonContext(convertToAction).SharedContext; ValidationInfo valInfo = BindingHelpers.GetValidationInfo(this, pt); if (pt.TryResolveSlot(context, name, out pts) && !IsBuiltinConversion(context, pts, name, pt)) { ParameterExpression tmp = Ast.Variable(typeof(object), "func"); Expression callExpr = resultConverter( Ast.Call( PythonOps.GetConversionHelper(returner, GetResultKind(convertToAction)), Ast.Dynamic( PythonContext.GetPythonContext(convertToAction).InvokeNone, typeof(object), PythonContext.GetCodeContext(convertToAction), tmp ) ) ); if (typeof(Extensible <>).MakeGenericType(toType).IsAssignableFrom(self.GetLimitType())) { // if we're doing a conversion to the underlying type and we're an // Extensible<T> of that type: // if an extensible type returns it's self in a conversion, then we need // to actually return the underlying value. If an extensible just keeps // returning more instances of it's self a stack overflow occurs - both // behaviors match CPython. callExpr = AstUtils.Convert(AddExtensibleSelfCheck(convertToAction, toType, self, callExpr), typeof(object)); } return(BindingHelpers.AddDynamicTestAndDefer( convertToAction, new DynamicMetaObject( Ast.Condition( MakeTryGetTypeMember( PythonContext.GetPythonContext(convertToAction), pts, self.Expression, tmp ), callExpr, AstUtils.Convert( ConversionFallback(convertToAction), typeof(object) ) ), self.Restrict(self.GetRuntimeType()).Restrictions ), new DynamicMetaObject[] { this }, valInfo, tmp )); } return(fallback()); }
/// <summary> /// WithStatement is translated to the DLR AST equivalent to /// the following Python code snippet (from with statement spec): /// /// mgr = (EXPR) /// exit = mgr.__exit__ # Not calling it yet /// value = mgr.__enter__() /// exc = True /// try: /// VAR = value # Only if "as VAR" is present /// BLOCK /// except: /// # The exceptional case is handled here /// exc = False /// if not exit(*sys.exc_info()): /// raise /// # The exception is swallowed if exit() returns true /// finally: /// # The normal and non-local-goto cases are handled here /// if exc: /// exit(None, None, None) /// /// </summary> public override MSAst.Expression Reduce() { // Five statements in the result... ReadOnlyCollectionBuilder <MSAst.Expression> statements = new ReadOnlyCollectionBuilder <MSAst.Expression>(6); ReadOnlyCollectionBuilder <MSAst.ParameterExpression> variables = new ReadOnlyCollectionBuilder <MSAst.ParameterExpression>(6); MSAst.ParameterExpression lineUpdated = Ast.Variable(typeof(bool), "$lineUpdated_with"); variables.Add(lineUpdated); //****************************************************************** // 1. mgr = (EXPR) //****************************************************************** MSAst.ParameterExpression manager = Ast.Variable(typeof(object), "with_manager"); variables.Add(manager); statements.Add( GlobalParent.AddDebugInfo( Ast.Assign( manager, _contextManager ), new SourceSpan(Start, _header) ) ); //****************************************************************** // 2. exit = mgr.__exit__ # Not calling it yet //****************************************************************** MSAst.ParameterExpression exit = Ast.Variable(typeof(object), "with_exit"); variables.Add(exit); statements.Add( MakeAssignment( exit, GlobalParent.Get( "__exit__", manager ) ) ); //****************************************************************** // 3. value = mgr.__enter__() //****************************************************************** MSAst.ParameterExpression value = Ast.Variable(typeof(object), "with_value"); variables.Add(value); statements.Add( GlobalParent.AddDebugInfoAndVoid( MakeAssignment( value, Parent.Invoke( new CallSignature(0), Parent.LocalContext, GlobalParent.Get( "__enter__", manager ) ) ), new SourceSpan(Start, _header) ) ); //****************************************************************** // 4. exc = True //****************************************************************** MSAst.ParameterExpression exc = Ast.Variable(typeof(bool), "with_exc"); variables.Add(exc); statements.Add( MakeAssignment( exc, AstUtils.Constant(true) ) ); //****************************************************************** // 5. The final try statement: // // try: // VAR = value # Only if "as VAR" is present // BLOCK // except: // # The exceptional case is handled here // exc = False // if not exit(*sys.exc_info()): // raise // # The exception is swallowed if exit() returns true // finally: // # The normal and non-local-goto cases are handled here // if exc: // exit(None, None, None) //****************************************************************** MSAst.ParameterExpression exception; MSAst.ParameterExpression nestedFrames = Ast.Variable(typeof(List <DynamicStackFrame>), "$nestedFrames"); variables.Add(nestedFrames); statements.Add( // try: AstUtils.Try( AstUtils.Try(// try statement body PushLineUpdated(false, lineUpdated), _var != null ? (MSAst.Expression)Ast.Block( // VAR = value _var.TransformSet(SourceSpan.None, value, PythonOperationKind.None), // BLOCK _body, AstUtils.Empty() ) : // BLOCK (MSAst.Expression)_body // except:, // try statement location ).Catch(exception = Ast.Variable(typeof(Exception), "exception"), // Python specific exception handling code TryStatement.GetTracebackHeader( this, exception, GlobalParent.AddDebugInfoAndVoid( Ast.Block( // exc = False MakeAssignment( exc, AstUtils.Constant(false) ), Ast.Assign( nestedFrames, Ast.Call(AstMethods.GetAndClearDynamicStackFrames) ), // if not exit(*sys.exc_info()): // raise AstUtils.IfThen( GlobalParent.Convert( typeof(bool), ConversionResultKind.ExplicitCast, GlobalParent.Operation( typeof(bool), PythonOperationKind.IsFalse, MakeExitCall(exit, exception) ) ), UpdateLineUpdated(true), Ast.Call( AstMethods.SetDynamicStackFrames, nestedFrames ), Ast.Throw( Ast.Call( AstMethods.MakeRethrowExceptionWorker, exception ) ) ) ), _body.Span ) ), Ast.Call( AstMethods.SetDynamicStackFrames, nestedFrames ), PopLineUpdated(lineUpdated), Ast.Empty() ) // finally: ).Finally( // if exc: // exit(None, None, None) AstUtils.IfThen( exc, GlobalParent.AddDebugInfoAndVoid( Ast.Block( Ast.Dynamic( GlobalParent.PyContext.Invoke( new CallSignature(3) // signature doesn't include function ), typeof(object), new MSAst.Expression[] { Parent.LocalContext, exit, AstUtils.Constant(null), AstUtils.Constant(null), AstUtils.Constant(null) } ), Ast.Empty() ), _contextManager.Span ) ) ) ); statements.Add(AstUtils.Empty()); return(Ast.Block(variables.ToReadOnlyCollection(), statements.ToReadOnlyCollection())); }
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; DynamicMetaObject func = GetMetaFunction(self); DynamicMetaObject call; if (Value.im_self == null) { // restrict to null self (Method is immutable so this is an invariant test) restrictions = restrictions.Merge( BindingRestrictions.GetExpressionRestriction( Ast.Equal( GetSelfExpression(self), AstUtils.Constant(null) ) ) ); if (args.Length == 0) { // this is an error, we pass null which will throw the normal error call = new DynamicMetaObject( Ast.Call( typeof(PythonOps).GetMethod("MethodCheckSelf"), PythonContext.GetCodeContext(callAction), self.Expression, AstUtils.Constant(null) ), restrictions ); } else { // this may or may not be an error call = new DynamicMetaObject( Ast.Block( MakeCheckSelf(callAction, signature, args), Ast.Dynamic( PythonContext.GetPythonContext(callAction).Invoke( BindingHelpers.GetCallSignature(callAction) ).GetLightExceptionBinder(callAction.SupportsLightThrow()), typeof(object), ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(ArrayUtils.Insert(func, args))) ) ), BindingRestrictions.Empty ); /*call = func.Invoke(callAction, ArrayUtils.Insert(func, args)); * call = new MetaObject( * Ast.Comma( * Ast.Call( * typeof(PythonOps).GetMethod("MethodCheckSelf"), * self.Expression, * args[0].Expression * ), * call.Expression * ), * call.Restrictions * );*/ } } else { // 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 im_self = GetMetaSelf(self); DynamicMetaObject[] newArgs = ArrayUtils.Insert(func, im_self, args); CallSignature newSig = new CallSignature(ArrayUtils.Insert(new Argument(ArgumentType.Simple), signature.GetArgumentInfos())); call = new DynamicMetaObject( Ast.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) )); } }
internal MSA.Expression <T> /*!*/ Transform <T>(AstGenerator /*!*/ gen) { Debug.Assert(gen != null); ScopeBuilder scope = new ScopeBuilder(); MSA.ParameterExpression[] parameters; MSA.Expression selfVariable; MSA.Expression rfcVariable; MSA.Expression parentScope; MSA.Expression language; MSA.Expression runtimeScopeVariable; MSA.Expression moduleVariable; MSA.Expression blockParameter; MSA.Expression currentMethodVariable; if (gen.CompilerOptions.IsEval) { parameters = new MSA.ParameterExpression[6]; parameters[0] = Ast.Parameter(typeof(RubyScope), "#scope"); selfVariable = parameters[1] = Ast.Parameter(typeof(object), "#self"); parameters[2] = Ast.Parameter(typeof(RubyModule), "#module"); blockParameter = parameters[3] = Ast.Parameter(typeof(Proc), "#block"); currentMethodVariable = parameters[4] = Ast.Parameter(typeof(RubyMethodInfo), "#method"); rfcVariable = parameters[5] = Ast.Parameter(typeof(RuntimeFlowControl), "#rfc"); if (gen.CompilerOptions.IsModuleEval) { runtimeScopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyScope)); parentScope = parameters[0]; moduleVariable = parameters[2]; } else { runtimeScopeVariable = parameters[0]; moduleVariable = null; parentScope = null; } language = null; } else { parameters = new MSA.ParameterExpression[2]; parentScope = parameters[0] = Ast.Parameter(typeof(Scope), "#globalScope"); language = parameters[1] = Ast.Parameter(typeof(LanguageContext), "#language"); selfVariable = scope.DefineHiddenVariable("#self", typeof(object)); rfcVariable = scope.DefineHiddenVariable("#rfc", typeof(RuntimeFlowControl)); runtimeScopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyScope)); blockParameter = null; currentMethodVariable = null; moduleVariable = null; } gen.EnterSourceUnit( scope, selfVariable, runtimeScopeVariable, blockParameter, rfcVariable, currentMethodVariable, gen.CompilerOptions.TopLevelMethodName, // method name null // parameters ); _definedScope.TransformLocals(scope); MSA.Expression scopeFactoryCall; if (gen.CompilerOptions.IsEval) { if (gen.CompilerOptions.IsModuleEval) { scopeFactoryCall = Methods.CreateModuleEvalScope.OpCall( scope.VisibleVariables(), parentScope, selfVariable, moduleVariable ); } else { scopeFactoryCall = null; } } else if (!gen.CompilerOptions.IsIncluded) { scopeFactoryCall = Methods.CreateMainTopLevelScope.OpCall(scope.VisibleVariables(), parentScope, language, selfVariable, rfcVariable, Ast.Constant(gen.SourceUnit.Path, typeof(string)), Ast.Constant(_dataOffset)); } else if (gen.CompilerOptions.IsWrapped) { scopeFactoryCall = Methods.CreateWrappedTopLevelScope.OpCall(scope.VisibleVariables(), parentScope, language, selfVariable, rfcVariable); } else { scopeFactoryCall = Methods.CreateTopLevelScope.OpCall(scope.VisibleVariables(), parentScope, language, selfVariable, rfcVariable); } MSA.Expression prologue, body; if (scopeFactoryCall != null) { prologue = Ast.Assign(runtimeScopeVariable, scopeFactoryCall); } else { prologue = null; } if (gen.SourceUnit.Kind == SourceCodeKind.InteractiveCode) { var resultVariable = scope.DefineHiddenVariable("#result", typeof(object)); var epilogue = Methods.PrintInteractiveResult.OpCall(runtimeScopeVariable, Ast.Dynamic(ConvertToSAction.Instance, typeof(MutableString), gen.CurrentScopeVariable, Ast.Dynamic(RubyCallAction.Make("inspect", RubyCallSignature.WithScope(0)), typeof(object), gen.CurrentScopeVariable, resultVariable ) ) ); body = gen.TransformStatements(prologue, _statements, epilogue, ResultOperation.Store(resultVariable)); } else { body = gen.TransformStatements(prologue, _statements, ResultOperation.Return); } body = gen.AddReturnTarget(scope.CreateScope(body)); gen.LeaveSourceUnit(); return(Ast.Lambda <T>( body, RubyExceptionData.TopLevelMethodName, parameters )); }
public virtual MSAst.Expression /*!*/ Dynamic(DynamicMetaObjectBinder /*!*/ binder, Type /*!*/ retType, MSAst.Expression /*!*/ arg0, MSAst.Expression /*!*/ arg1, MSAst.Expression /*!*/ arg2, MSAst.Expression /*!*/ arg3) { return(Ast.Dynamic(binder, retType, arg0, arg1, arg2, arg3)); }