public override MSAst.Expression Reduce() { ReadOnlyCollectionBuilder <MSAst.Expression> statements = new ReadOnlyCollectionBuilder <MSAst.Expression>(); for (int i = 0; i < _names.Length; i++) { statements.Add( // _references[i] = PythonOps.Import(<code context>, _names[i]) GlobalParent.AddDebugInfoAndVoid( AssignValue( Parent.GetVariableExpression(_variables[i]), LightExceptions.CheckAndThrow( Expression.Call( _asNames[i] == null ? AstMethods.ImportTop : AstMethods.ImportBottom, Parent.LocalContext, // 1st arg - code context AstUtils.Constant(_names[i].MakeString()), // 2nd arg - module name AstUtils.Constant(_forceAbsolute ? 0 : -1) // 3rd arg - absolute or relative imports ) ) ), _names[i].Span ) ); } statements.Add(AstUtils.Empty()); return(GlobalParent.AddDebugInfo(Ast.Block(statements.ToReadOnlyCollection()), Span)); }
/// <summary> /// Move to the next item in this iterable /// </summary> /// <returns>True if moving was successfull</returns> public bool MoveNext() { if (_nextMethod == null) { if (!PythonOps.TryGetBoundAttr(_baseObject, "__next__", out _nextMethod) || _nextMethod == null) { throw PythonOps.TypeError("instance has no next() method"); } } try { _current = DefaultContext.Default.LanguageContext.CallLightEh(DefaultContext.Default, _nextMethod); Exception lightEh = LightExceptions.GetLightException(_current); if (lightEh != null) { if (lightEh is StopIterationException) { return(false); } throw lightEh; } return(true); } catch (StopIterationException) { return(false); } }
/// <summary> /// Move to the next item in this iterable /// </summary> /// <returns>True if moving was successfull</returns> public bool MoveNext() { PythonTypeOps.TryGetOperator(DefaultContext.Default, _baseObject, "__next__", out object nextMethod); if (nextMethod == null) { throw PythonOps.TypeErrorForNotAnIterator(_baseObject); } try { _current = DefaultContext.Default.LanguageContext.CallLightEh(DefaultContext.Default, nextMethod); Exception lightEh = LightExceptions.GetLightException(_current); if (lightEh != null) { if (lightEh is StopIterationException) { return(false); } throw lightEh; } return(true); } catch (StopIterationException) { return(false); } }
private object GetCachedValue(bool lightThrow) { if (_global == null) { _global = ((PythonContext)_context.LanguageContext).GetModuleGlobalCache(_name); } if (_global.IsCaching) { if (_global.HasValue) { return(_global.Value); } } else { object value; if (_context.TryLookupBuiltin(_name, out value)) { return(value); } } if (lightThrow) { return(LightExceptions.Throw(PythonOps.GlobalNameError(_name))); } throw PythonOps.GlobalNameError(_name); }
public object close() { // This is nop if the generator is already closed. // Optimization to avoid throwing + catching an exception if we're already closed. if (Closed) { return(null); } // This function body is the psuedo code straight from Pep 342. try { object res = @throw(new GeneratorExitException()); Exception lightEh = LightExceptions.GetLightException(res); if (lightEh != null) { if (lightEh is StopIterationException || lightEh is GeneratorExitException) { return(null); } return(lightEh); } // Generator should not have exited normally. return(LightExceptions.Throw(new RuntimeException("generator ignored GeneratorExit"))); } catch (StopIterationException) { // Ignore, clear any stack frames we built up } catch (GeneratorExitException) { // Ignore, clear any stack frames we built up } return(null); }
public object __next__() { // Python's language policy on generators is that attempting to access after it's closed (returned) // just continues to throw StopIteration exceptions. if (Closed) { return(LightExceptions.Throw(PythonOps.StopIteration())); } object res = NextWorker(); if (res == OperationFailed.Value) { if (FinalValue is null) { return(LightExceptions.Throw(new PythonExceptions._StopIteration().InitAndGetClrException())); } else { return(LightExceptions.Throw(new PythonExceptions._StopIteration().InitAndGetClrException(FinalValue))); } } return(res); }
public object GetErrorLightThrow(CallSite site, TSelfType target, CodeContext context) { if (target != null && target.GetType() == _type && (object)_extMethods == (object)context.ModuleContext.ExtensionMethods) { return(LightExceptions.Throw(PythonOps.AttributeErrorForObjectMissingAttribute(target, _name))); } return(((CallSite <Func <CallSite, TSelfType, CodeContext, object> >)site).Update(site, target, context)); }
/// <summary> /// Gateway into importing ... called from Ops. Performs the initial import of /// a module and returns the module. /// </summary> public static object Import(CodeContext /*!*/ context, string fullName, PythonTuple from, int level) { if (level < 0) { throw new ArgumentException("level must be >= 0", nameof(level)); } return(LightExceptions.CheckAndThrow(ImportLightThrow(context, fullName, from, level))); }
private object ThrowThrowable() { object[] throwableBackup = _excInfo; // Clear it so that any future Next()/MoveNext() call doesn't pick up the exception again. _excInfo = null; // This may invoke user code such as __init__, thus MakeException may throw. // Since this is invoked from the generator's body, the generator can catch this exception. return(LightExceptions.Throw(PythonOps.MakeException(Context, throwableBackup[0], throwableBackup[1], throwableBackup[2]))); }
protected override Expression VisitUnary(UnaryExpression node) { if (node.NodeType == ExpressionType.Throw) { Expression exception = node.Operand ?? _rethrow; return Expression.Block( Expression.Assign(_lastValue, LightExceptions.Throw(Visit(exception))), PropagateException(node.Type) ); } return base.VisitUnary(node); }
private static void PrintLambda(Expression <Func <List <string>, object> > lambda, List <string> record, List <string> rewriteRecord) { for (int i = 0; i < Math.Min(record.Count, rewriteRecord.Count); i++) { Console.WriteLine(record[i]); Console.WriteLine(rewriteRecord[i]); Console.WriteLine(); } #if CLR2 Console.WriteLine("Before: " + Environment.NewLine + lambda.DebugView); Console.WriteLine("After: " + Environment.NewLine + LightExceptions.Rewrite(lambda).DebugView); #endif }
// Generate AST statement to call $gen.CheckThrowable() on the Python Generator. // This needs to be injected at any yield suspension points, mainly: // - at the start of the generator body // - after each yield statement. static internal MSAst.Expression CreateCheckThrowExpression(SourceSpan span) { MSAst.Expression instance = GeneratorRewriter._generatorParam; Debug.Assert(instance.Type == typeof(IronPython.Runtime.PythonGenerator)); MSAst.Expression s2 = LightExceptions.CheckAndThrow( Expression.Call( AstMethods.GeneratorCheckThrowableAndReturnSendValue, instance ) ); return(s2); }
public object LightThrowTarget(CallSite site, object instance, CodeContext context) { if (instance is OldInstance oi) { object res; if (oi.TryGetBoundCustomMember(context, _name, out res)) { return(res); } return(LightExceptions.Throw(PythonOps.AttributeError("{0} instance has no attribute '{1}'", oi._class.Name, _name))); } return(((CallSite <Func <CallSite, object, CodeContext, object> >)site).Update(site, instance, context)); }
internal static DynamicMetaObject CheckLightThrowMO(DynamicMetaObjectBinder call, DynamicMetaObject res, BindingTarget target) { if (target.Success && target.Overload.ReflectionInfo.IsDefined(typeof(LightThrowingAttribute), false)) { if (!call.SupportsLightThrow()) { res = new DynamicMetaObject( LightExceptions.CheckAndThrow(res.Expression), res.Restrictions ); } } return(res); }
public object LightThrowTarget(CallSite site, object self, CodeContext context) { if (self != null && self.GetType() == typeof(PythonModule)) { var res = ((PythonModule)self).GetAttributeNoThrow(context, _name); if (res == OperationFailed.Value) { return(LightExceptions.Throw( PythonOps.AttributeErrorForObjectMissingAttribute(self, _name) )); } return(res); } return(Update(site, self, context)); }
public object next() { // Python's language policy on generators is that attempting to access after it's closed (returned) // just continues to throw StopIteration exceptions. if (Closed) { return(LightExceptions.Throw(new StopIterationException())); } object res = NextWorker(); if (res == OperationFailed.Value) { return(LightExceptions.Throw(new StopIterationException())); } return(res); }
private static IEnumerable <Expression> CallBuilder(LightExceptionTests self) { yield return(AddLogging(LightExceptions.CheckAndThrow(Expression.Call(typeof(LightExceptionTests).GetMethod("SomeCall"))), "call")); yield return(AddLogging(Expression.Call(typeof(LightExceptionTests).GetMethod("ThrowingCall")), "call throw")); yield return(AddLogging(Expression.Call(typeof(LightExceptionTests).GetMethod("ThrowingCallInvalidOp")), "call throw invalidop")); yield return(AddLogging(LightExceptions.CheckAndThrow(Expression.Call(typeof(LightExceptionTests).GetMethod("LightThrowingCall"))), "call throw")); yield return(AddLogging(LightExceptions.CheckAndThrow(Expression.Call(typeof(LightExceptionTests).GetMethod("LightThrowingCallInvalidOp"))), "call throw invalidop")); yield return(AddLogging(Expression.Dynamic(new LightExBinder("test", false), typeof(object), Expression.Constant(42)), "dynamic throw")); yield return(AddLogging( Expression.Dynamic(new LightExBinder("test", false), typeof(object), Expression.Dynamic(new LightExBinder("foo", false), typeof(object), Expression.Constant(42))), "dynamic nothrow")); }
// Pep 342 says generators now have finalizers (__del__) that call Close() private void Finalizer() { // if there are no except or finally blocks then closing the // generator has no effect. if (CanSetSysExcInfo || ContainsTryFinally) { try { // This may run the users generator. object res = close(); Exception ex = LightExceptions.GetLightException(res); if (ex != null) { HandleFinalizerException(ex); } } catch (Exception e) { HandleFinalizerException(e); } } }
private object @throw(object type, object value, object traceback, bool finalizing) { // The Pep342 explicitly says "The type argument must not be None". // According to CPython 2.5's implementation, a null type argument should: // - throw a TypeError exception (just as Raise(None) would) *outside* of the generator's body // (so the generator can't catch it). // - not update any other generator state (so future calls to Next() will still work) if (type == null) { // Create the appropriate exception and throw it. throw PythonOps.MakeExceptionTypeError(null, true); } // Set fields which will then be used by CheckThrowable. // We create the actual exception from inside the generator so that if the exception's __init__ // throws, the traceback matches that which we get from CPython2.5. _excInfo = new object[] { type, value, traceback }; Debug.Assert(_sendValue == null); // Pep explicitly says that Throw on a closed generator throws the exception, // and not a StopIteration exception. (This is different than Next()). if (Closed) { // this will throw the exception that we just set the fields for. var throwable = CheckThrowable(); if (throwable != null) { return(throwable); } } if (finalizing) { // we are running on the finalizer thread - things can be already collected return(LightExceptions.Throw(PythonOps.StopIteration())); } if (!((IEnumerator)this).MoveNext()) { return(LightExceptions.Throw(PythonOps.StopIteration())); } return(CurrentValue); }
public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion) { var ex = Expression.New(typeof(MissingMemberException)); Expression body; if (Name == "foo") { body = target.Expression; } else if (_supportsLightEx) { body = LightExceptions.Throw(ex, typeof(object)); } else { body = Expression.Throw(ex, typeof(object)); } return(new DynamicMetaObject( body, BindingRestrictions.GetTypeRestriction(target.Expression, target.Value.GetType()) )); }
public static object a2b_qp(object data, object header) { return(LightExceptions.Throw(new NotImplementedException())); }
internal MSAst.Expression ReduceWorker() { var retStmt = _body as ReturnStatement; if (retStmt != null && (_languageFeatures == ModuleOptions.None || _languageFeatures == (ModuleOptions.ExecOrEvalCode | ModuleOptions.Interpret) || _languageFeatures == (ModuleOptions.ExecOrEvalCode | ModuleOptions.Interpret | ModuleOptions.LightThrow))) { // for simple eval's we can construct a simple tree which just // leaves the value on the stack. Return's can't exist in modules // so this is always safe. Debug.Assert(!IsModule); var ret = (ReturnStatement)_body; Ast simpleBody; if ((_languageFeatures & ModuleOptions.LightThrow) != 0) { simpleBody = LightExceptions.Rewrite(retStmt.Expression.Reduce()); } else { simpleBody = retStmt.Expression.Reduce(); } var start = IndexToLocation(ret.Expression.StartIndex); var end = IndexToLocation(ret.Expression.EndIndex); return(Ast.Block( Ast.DebugInfo( _document, start.Line, start.Column, end.Line, end.Column ), AstUtils.Convert(simpleBody, typeof(object)) )); } ReadOnlyCollectionBuilder <MSAst.Expression> block = new ReadOnlyCollectionBuilder <MSAst.Expression>(); AddInitialiation(block); if (IsModule) { block.Add(AssignValue(GetVariableExpression(DocVariable), Ast.Constant(GetDocumentation(_body)))); } if (!(_body is SuiteStatement) && _body.CanThrow) { // we only initialize line numbers in suite statements but if we don't generate a SuiteStatement // at the top level we can miss some line number updates. block.Add(UpdateLineNumber(_body.Start.Line)); } block.Add(_body); MSAst.Expression body = Ast.Block(block.ToReadOnlyCollection()); body = WrapScopeStatements(body, Body.CanThrow); // new ComboActionRewriter().VisitNode(Transform(ag)) body = AddModulePublishing(body); body = AddProfiling(body); if ((((PythonCompilerOptions)_compilerContext.Options).Module & ModuleOptions.LightThrow) != 0) { body = LightExceptions.Rewrite(body); } body = Ast.Label(FunctionDefinition._returnLabel, AstUtils.Convert(body, typeof(object))); if (body.Type == typeof(void)) { body = Ast.Block(body, Ast.Constant(null)); } return(body); }
public override MSAst.Expression Reduce() { // allocated all variables here so they won't be shared w/ other // locals allocated during the body or except blocks. MSAst.ParameterExpression?lineUpdated = null; MSAst.ParameterExpression?runElse = null; MSAst.ParameterExpression?previousExceptionContext = null; if (Else != null || _handlers.Length > 0) { lineUpdated = Ast.Variable(typeof(bool), "$lineUpdated_try"); if (Else != null) { runElse = Ast.Variable(typeof(bool), "run_else"); } } // don't allocate locals below here... MSAst.Expression body = Body; MSAst.Expression? @else = Else; MSAst.Expression? @catch; MSAst.Expression result; MSAst.ParameterExpression?exception; if (_handlers.Length > 0) { previousExceptionContext = Ast.Variable(typeof(Exception), "$previousException"); exception = Ast.Variable(typeof(Exception), "$exception"); @catch = TransformHandlers(exception, previousExceptionContext); } else if (Finally != null) { exception = Ast.Variable(typeof(Exception), "$exception"); @catch = null; } else { exception = null; @catch = null; } // We have else clause, must generate guard around it if (@else != null) { Debug.Assert(@catch != null); // run_else = true; // try { // try_body // } catch ( ... ) { // run_else = false; // catch_body // } // if (run_else) { // else_body // } result = Ast.Block( Ast.Assign(runElse, AstUtils.Constant(true)), // save existing line updated, we could choose to do this only for nested exception handlers. PushLineUpdated(false, lineUpdated), LightExceptions.RewriteExternal( AstUtils.Try( Parent.AddDebugInfo(AstUtils.Empty(), new SourceSpan(Span.Start, GlobalParent.IndexToLocation(HeaderIndex))), Ast.Assign(previousExceptionContext, Ast.Call(AstMethods.SaveCurrentException)), body, AstUtils.Constant(null) ).Catch(exception, Ast.Assign(runElse, AstUtils.Constant(false)), @catch, // restore existing line updated after exception handler completes PopLineUpdated(lineUpdated), Ast.Assign(exception, Ast.Constant(null, typeof(Exception))), AstUtils.Constant(null) ) ), AstUtils.IfThen(runElse, @else ), AstUtils.Empty() ); } else if (@catch != null) // no "else" clause // try { // <try body> // } catch (Exception e) { // ... catch handling ... // } // { result = LightExceptions.RewriteExternal( AstUtils.Try( GlobalParent.AddDebugInfo(AstUtils.Empty(), new SourceSpan(Span.Start, GlobalParent.IndexToLocation(HeaderIndex))), // save existing line updated PushLineUpdated(false, lineUpdated), Ast.Assign(previousExceptionContext, Ast.Call(AstMethods.SaveCurrentException)), body, AstUtils.Constant(null) ).Catch(exception, @catch, // restore existing line updated after exception handler completes PopLineUpdated(lineUpdated), Ast.Assign(exception, Ast.Constant(null, typeof(Exception))), AstUtils.Constant(null) ) ); } else { result = body; } return(Ast.Block( GetVariables(lineUpdated, runElse, previousExceptionContext), AddFinally(result), AstUtils.Default(typeof(void)) )); }
public static void IronPython2_Gh563() { LightExceptions.Rewrite(Expression.Constant(3.14, typeof(double))).Reduce(); }
public override int Run(InterpretedFrame frame) { frame.Push(ScriptingRuntimeHelpers.BooleanToObject(LightExceptions.IsLightException(frame.Pop()))); return(+1); }
/// <summary> /// Gateway into importing ... called from Ops. Performs the initial import of /// a module and returns the module. /// </summary> public static object Import(CodeContext /*!*/ context, string fullName, PythonTuple from, int level) { return(LightExceptions.CheckAndThrow(ImportLightThrow(context, fullName, from, level))); }
public override int Run(InterpretedFrame frame) { frame.Push(LightExceptions.IsLightException(frame.Pop())); return(+1); }
public static void RunTests() { var param = Expression.Parameter(typeof(Exception), "foo"); var lambdax = Expression.Lambda <Func <object> >( Expression.Block( LightExceptions.RewriteExternal( Expression.TryCatch( Expression.Default(typeof(object)), Expression.Catch(param, Expression.Default(typeof(object))) ) ), LightExceptions.RewriteExternal( Expression.TryCatch( Expression.Default(typeof(object)), Expression.Catch(param, Expression.Default(typeof(object))) ) ) ) ); lambdax.Compile()(); CompilerHelpers.LightCompile(lambdax)(); var builder = new LightExceptionTests(); List <string> record = new List <string>(); List <string> rewriteRecord = new List <string>(); int testCount = 0; try { foreach (var lambda in builder.MakeLambda()) { // run each test in normal and lightweight exception modes, make sure they have the same result try { object res = lambda.Compile()(record); if (res != null) { record.Add(res.ToString()); } } catch (Exception e) { record.Add(String.Format("EXCEPTION {0}", e.GetType())); } try { object res = ((Expression <Func <List <string>, object> >)LightExceptions.Rewrite(lambda)).Compile()(rewriteRecord); Exception e = LightExceptions.GetLightException(res); if (e != null) { rewriteRecord.Add(String.Format("EXCEPTION {0}", e.GetType())); } else if (res != null) { rewriteRecord.Add(res.ToString()); } } catch (Exception e) { rewriteRecord.Add(String.Format("EXCEPTION {0}", e.GetType())); } if (record.Count != rewriteRecord.Count) { PrintLambda(lambda, record, rewriteRecord); throw new Exception("Records differ in length"); } for (int i = 0; i < record.Count; i++) { if (record[i] != rewriteRecord[i]) { PrintLambda(lambda, record, rewriteRecord); throw new Exception("Records differ"); } } record.Clear(); rewriteRecord.Clear(); testCount++; } } finally { Console.Write("Ran {0} tests", testCount); } }
public static object LightThrowingCallInvalidOp() { return(LightExceptions.Throw(new InvalidOperationException())); }
public static object LightThrowingCall() { return(LightExceptions.Throw(new Exception())); }