[IronPython] Parser is not accessible anymore in IP2A6

Martin Maly Martin.Maly at microsoft.com
Fri Nov 30 18:20:29 CET 2007


Hi David,

This is actually a bug in the DLR code. What is happening, and what made your brain hurt, was the code which creates instructions for DLR how to do a given operation, in this case how to call the CreateParser method. Since it is not a public method, we have to invoke it through reflection. And because it is a static method, the instance must be null. Here's where the problem lies. The null at execution time is expressed via Ast.Null() expression node at code generation time. So to fix this on your machine, you can replace line 156 in MethodTarget.cs which reads:

Expression instance = mi.IsStatic ? null : _instanceBuilder.ToExpression(context, parameters);

With:

Expression instance = mi.IsStatic ? Ast.Null() : _instanceBuilder.ToExpression(context, parameters);

I'll check the fix soon (after due testing) so it should be on codeplex in matter of days and also in the next release.

Thanks for a great repro!

Martin

-----Original Message-----
From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of David.Lawler at franke.com
Sent: Wednesday, November 28, 2007 1:46 PM
To: Discussion of IronPython
Subject: Re: [IronPython] Parser is not accessible anymore in IP2A6

> Yes, Parser being internal definitely causes the error. It is a good
> question whether it is a permanent change because there are pros and
> cons going both ways. Let me open a bug on this since it is
> something we need to make decision on. In the meantime, as a
> temporary workaround (emphasizing the temporary workaround) you can
> use -X:PrivateBinding flag with IronPython to get access to the
> internal/private classes.
>
> The bug I opened is here:
>
> http://www.codeplex.com/IronPython/WorkItem/View.aspx?WorkItemId=14105
>
> Feel free to vote/comment on it and also keep an eye on it for the
> ultimate resolution.
>
> Thanks for the feedback!
> Martin
>

Well - that SHOULD work - but does not.  If you take the following example
program:

import clr

clr.AddReference('IronPython')
clr.AddReference('Microsoft.Scripting')

from System.Text import Encoding
import IronPython
import Microsoft.Scripting

path = "PythonParserTest.py"
pe = IronPython.Hosting.PythonEngine.CurrentEngine
enc = Encoding.Default
s = Microsoft.Scripting.Hosting.SourceUnit.CreateFileUnit(pe, path, enc)
c = Microsoft.Scripting.CompilerContext(s)

p = IronPython.Compiler.Parser.CreateParser(c,
IronPython.PythonEngineOptions())

ast = p.ParseFile(True)

print "all done"

save it as PythonParserTest.py and run it you get this:

ipy -X:PrivateBinding -X:ExceptionDetail PythonParserTest.py
Value cannot be null.
Parameter name: expression
   at Microsoft.Scripting.Ast.Ast.ConvertHelper(Expression expression,
Type type
)
   at
Microsoft.Scripting.Generation.MethodTarget.MakeExpression(ActionBinder bi
nder, StandardRule rule, Expression[] parameters)
   at
Microsoft.Scripting.Generation.MethodTarget.MakeExpression(ActionBinder bi
nder, StandardRule rule, Expression[] parameters, Type[] knownTypes)
   at
Microsoft.Scripting.Actions.CallBinderHelper`2.MakeMethodBaseRule(MethodBa
se[] targets)
   at Microsoft.Scripting.Actions.CallBinderHelper`2.MakeRule()
   at IronPython.Runtime.Types.BuiltinFunction.MakeCallRule[T](CallAction
action
, CodeContext context, Object[] args)
   at
IronPython.Runtime.Types.BuiltinFunction.Microsoft.Scripting.IDynamicObjec
t.GetRule[T](DynamicAction action, CodeContext context, Object[] args)
   at
Microsoft.Scripting.Actions.ActionBinder.UpdateSiteAndExecute[T](CodeConte
xt callerContext, DynamicAction action, Object[] args, Object site, T&
target, R
uleSet`1& rules)
   at
Microsoft.Scripting.Actions.FastDynamicSite`4.UpdateBindingAndInvoke(T0 ar
g0, T1 arg1, T2 arg2)
   at
Microsoft.Scripting.Actions.DynamicSiteHelpers.UninitializedTargetHelper`7
.FastInvoke3(FastDynamicSite`4 site, T0 arg0, T1 arg1, T2 arg2)
   at Microsoft.Scripting.Actions.FastDynamicSite`4.Invoke(T0 arg0, T1
arg1, T2
arg2)
   at __main__$mod_1.Initialize(CodeContext ) in PythonParserTest.py:line
16
   at Microsoft.Scripting.ScriptCode.Run(CodeContext codeContext, Boolean
tryEva
luate)
   at Microsoft.Scripting.ScriptModule.Execute()
   at IronPython.Hosting.PythonCommandLine.RunFileWorker(String fileName)
   at IronPython.Hosting.PythonCommandLine.RunFile(String filename)

if you make your own version of IronPython 2A6 with Parser set to public
rather
than internal, then the above example works.  The problem appears to be in
MethodTarget.cs
around line 150 or so:

                // Private binding, invoke via reflection
                if (mi != null) {
                    Expression instance = mi.IsStatic ? null :
_instanceBuilder.ToExpression(context, parameters);
                    call = Ast.Call(
                        Ast.RuntimeConstant(mi),
                        typeof(MethodInfo).GetMethod("Invoke", new Type[]
{ typeof(object), typeof(object[]) }),
                        Ast.ConvertHelper(instance, typeof(object)),
                        Ast.NewArrayHelper(typeof(object[]), args)
                    );
                } else {
                    call = Ast.Call(
                        Ast.RuntimeConstant((ConstructorInfo)Method),
                        typeof(ConstructorInfo).GetMethod("Invoke", new
Type[] { typeof(object[]) }),
                        Ast.NewArrayHelper(typeof(object[]), args)
                    );
                }

where it seems that the 'invoke via reflection for private bindings' has
issues in
Ast.ConvertHelper.  However, as I tried to understand the problem further
I developed
an enormous brain cramp.  I am so happy that I mostly write business
software and not compilers!
This is not of huge importance to me but I would think that you would want
to solve this
for the poor souls out there who are (or will be) trying to produce
editors/IDEs or other
tools for IronPython (think Intellisense and/or code completion).

Regards,

David
_______________________________________________
Users mailing list
Users at lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com



More information about the Ironpython-users mailing list