0.9.0 throws NullReferenceException

Mar 9, 2011 at 2:17 PM

Hi all,

I just downloaded the latest version (0.9.0).  I'm getting a NullReferenceException that I wasn't getting previously.

Here's the call stack:

   at Jint.Marshal.ProxyHelper.WrapSetProperty(PropertyInfo prop, Marshaller marshaller) in C:\Users\my_user_name\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Marshal\ProxyHelper.cs:line 441
   at Jint.Marshaller.WrapSetProperty(PropertyInfo prop) in C:\Users\my_user_name\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Marshal.cs:line 328
   at Jint.Marshaller.MarshalPropertyInfo(PropertyInfo prop, JsDictionaryObject owner) in C:\Users\my_user_name\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Marshal.cs:line 368
   at Jint.Native.NativeConstructor..ctor(Type type, IGlobal global, JsObject PrototypePrototype, JsObject prototype) in C:\Users\my_user_name\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Native\NativeConstructor.cs:line 126
   at Jint.Native.NativeTypeConstructor.Wrap[T](T value) in C:\Users\my_user_name\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Native\NativeTypeConstructor.cs:line 43
   at Jint.Marshaller.CreateConstructor(Type t) in C:\Users\my_user_name\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Marshal.cs:line 150
   at Jint.Marshaller.MarshalType(Type t) in C:\Users\my_user_name\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Marshal.cs:line 138
   at Jint.Marshaller.MarshalClrValue[T](T value) in C:\Users\my_user_name\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Marshal.cs:line 128
   at Jint.Native.JsGlobal.WrapClr(Object value) in C:\Users\my_user_name\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Native\JsGlobal.cs:line 336
   at Jint.JintEngine.SetParameter(String name, Object value) in C:\Users\my_user_name\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\JintEngine.cs:line 314

My application code is:

HttpContext.Current.Items[modelPage] = new Jint.JintEngine();
engine = HttpContext.Current.Items[modelPage] as Jint.JintEngine;
engine.SetParameter("Page", p_control.Page); // error thrown here

p_control.Page is a ASP.NET page, the code-behind of which is inherited from a custom class, WebUtilities.Page, which has a property BreadcrumbGuid with a public getter and an internal setter.

The bit of Jint code that seems to be making the trouble in WrapSetProperty is:

MethodInfo info = prop.GetSetMethod();
var code = dm.GetILGenerator();
if (!info.IsStatic) {

It's assuming that there IS a set method, but in this case, there isn't.  I can try to make a simple test case in the 0.9.0 branch, but I don't have time right now to try to come up with a fix.

For now, I'll keep using my locally patched version of 0.8.9 (with a fix I needed that is in 0.9.0) and add to the patch a different version of of Antlr (which I need because I'm also using NHibernate.)

Thank you again for the great tool.  Cheers!

Mar 9, 2011 at 2:22 PM
Edited Mar 9, 2011 at 2:39 PM

Here's the test case.

public class ClassWithPropertyWithPublicSetterAndInternalGetter
{
    public Guid? JustAGuid
    {
        get;
        internal set;
    }
}

[TestMethod]
public void AddClassWithPublicGetInternalSet()
{
    Jint.JintEngine engine = new Jint.JintEngine();
    var testInstance = new ClassWithPropertyWithPublicSetterAndInternalGetter();

    engine.SetParameter("testInstance", testInstance);
}

Error Message:

Test method Jint.Tests.Fixtures.AddClassWithPublicGetInternalSet threw exception:
System.NullReferenceException: Object reference not set to an instance of an object.

Error Stack Trace

Jint.Marshal.ProxyHelper.WrapSetProperty(PropertyInfo prop, Marshaller marshaller) in C:\Users\dlavelle\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Marshal\ProxyHelper.cs: line 441
Jint.Marshaller.WrapSetProperty(PropertyInfo prop) in C:\Users\dlavelle\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Marshal.cs: line 328
Jint.Marshaller.MarshalPropertyInfo(PropertyInfo prop, JsDictionaryObject owner) in C:\Users\dlavelle\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Marshal.cs: line 368
Jint.Native.NativeConstructor..ctor(Type type, IGlobal global, JsObject PrototypePrototype, JsObject prototype) in C:\Users\dlavelle\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Native\NativeConstructor.cs: line 126
Jint.Native.NativeTypeConstructor.Wrap[T](T value) in C:\Users\dlavelle\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Native\NativeTypeConstructor.cs: line 43
Jint.Marshaller.CreateConstructor(Type t) in C:\Users\dlavelle\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Marshal.cs: line 150
Jint.Marshaller.MarshalType(Type t) in C:\Users\dlavelle\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Marshal.cs: line 138
Jint.Marshaller.MarshalClrValue[T](T value) in C:\Users\dlavelle\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Marshal.cs: line 128
Jint.Native.JsGlobal.WrapClr(Object value) in C:\Users\dlavelle\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\Native\JsGlobal.cs: line 336
Jint.JintEngine.SetParameter(String name, Object value) in C:\Users\dlavelle\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint\JintEngine.cs: line 314
Jint.Tests.Fixtures.AddClassWithPublicGetInternalSet() in C:\Users\dlavelle\Documents\Jint-0.9.0-sources\Jint-0.9.0-sources\Jint.Tests\Fixtures.cs: line 1550

Mar 9, 2011 at 7:39 PM

So I looked at the Jint code (I need this to be working for me ASAP) and I made the following change:

        /// <summary>
        /// Marshals a native property to a descriptor
        /// </summary>
        /// <param name="prop">Property to marshal</param>
        /// <param name="owner">Owner of the returned descriptor</param>
        /// <returns>A descriptor</returns>
        public NativeDescriptor MarshalPropertyInfo(PropertyInfo prop, JsDictionaryObject owner)
        {
            JsGetter getter;
            JsSetter setter = null;

            if (prop.CanRead && prop.GetGetMethod() != null) // I added "&& prop.GetGetMethod() != null" to match change below.
            {
                getter = WrapGetProperty(prop);
            }
            else
            {
                getter = delegate(JsDictionaryObject that)
                {
                    return JsUndefined.Instance;
                };
            }

            if (prop.CanWrite && prop.GetSetMethod() != null) // I added " && prop.GetSetMethod() != null".
            {
                setter = (JsSetter)WrapSetProperty(prop);
            }

            return setter == null ? new NativeDescriptor(owner, prop.Name, getter) { Enumerable = true } : new NativeDescriptor(owner, prop.Name, getter, setter) { Enumerable = true };
        }

I am not claiming that this is correct, only that 1) it works for me, and 2) the new test case, as well as any existing test cases, work.

Mar 9, 2011 at 9:09 PM

it has been fixed already and exactly the way you've post ;) see change set f742cf156dd1.

Mar 10, 2011 at 1:34 PM

Oh, awesome.  Next time I will check the issue tracker!  Thanks!  =)