Late-bound property access w/o a new language?

Dec 6, 2009 at 10:47 AM
Edited Dec 7, 2009 at 8:41 PM

Would it make sense to use the DLR's call sites to speed operation of a data serialization/deserialization library?  Trying to figure out how this would work, I tried to see if I could use DLR's dynamic code generation do this without writing a new DLR language.   It seemed like the support for the internal "Invariant" language might do the trick, but I've run into a few problems in my initial attempts.   The idea is to use DLR to change the value of the Key property in a DictionaryEntry:

var runtime = ScriptRuntime.CreateFromConfiguration();
var ops = runtime.Operations;
var de = new DictionaryEntry("Key", "Value");
ops.SetMember(de, "Key", "Changed");  // Late-bound property set
Console.WriteLine(de.Key);

The call to CreateFromConfiguration() is failing complaining that "ScriptRuntimeSetup must have at least one LanguageSetup"  [workitem:4829].  OK, I can get around that with a dummy language:

class Foo { }

static void Main(string[] args)
{
    var setup = new ScriptRuntimeSetup();
    setup.LanguageSetups.Add(
        new LanguageSetup(typeof(Foo)
            .AssemblyQualifiedName, 
            "Foo language"));
    var  runtime = new ScriptRuntime(setup);
    var ops = runtime.Operations;
    DictionaryEntry de = new DictionaryEntry("Key", "Value");
    ops.SetMember(de, "Key", "Changed");  // Late-bound property set
    Console.WriteLine(de.Key);
}

The next problem seem harder [workitem:4828], ops.SetMember() is throwing a NotImplementedException.  Same exception with InvokeMember(), and GetMember() throws a MissingMemberException    Digging further, I've had to implement my own LanguageContext & DefaultBinder classes, and even when I get dynamic property get's working, the property set seems to be silently failing.   Perhaps I've missed tomething fundamental.  

If I'm barking up the wrong tree here, a simple working example along the lines of the above would really help.   

Dec 10, 2009 at 9:39 AM
Edited Dec 10, 2009 at 9:41 AM

Answering my own question:   Yes, it seems to make sense, but it requires writing a new "language". 

 I've done it it prototype form, with very impressive performance when I implement my own call site caching.  

I submitted a bunch of bugs for issues discovered writing the prototype, all but one closed by the DLR team without fixing them.   Hmm...

Coordinator
Dec 10, 2009 at 7:12 PM

You’ll need to use more than the invariant language – you’ll want to use the default binder.  The invariant language doesn’t really do anything.  In the latest sources using the default binder has been greatly simplified.  I’m sure these have been pushed to IronPython.codeplex.com, they’re probably at dlr.codeplex.com but I haven’t checked.  But a simple example of GetMember is:

      class DefaultGetMemberBinder : GetMemberBinder {

            private readonly DefaultBinder _binder = new DefaultBinder();

            public DefaultGetMemberBinder(string name)

                : base(name, false) {

            }

            public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion) {

                var res = _binder.GetMember(Name, target);

                if (res.LimitType.IsValueType) {

                    res = new DynamicMetaObject(Expression.Convert(res.Expression, typeof(object)), res.Restrictions);

                }

                return res;

            }

        }

            var binder = new DefaultBinder();

            CallSite<Func<CallSite, object, object>> site = CallSite<Func<CallSite, object, object>>.Create(new DefaultGetMemberBinder("Count"));

            var list = new List<object>();

            site.Target(site, list);

So you don’t need a ScriptRuntime or anything else – you can just new up the default binder and use its various methods to perform the binding.

From: BurtHarris [mailto:notifications@codeplex.com]
Sent: Sunday, December 06, 2009 2:48 AM
To: Dino Viehland
Subject: Late-bound property access w/o a new language? [dlr:77266]

From: BurtHarris

Would it make sense to use the DLR's call sites to speed operation of a data serialization/deserialization library? Trying to figure out how this would work, I tried to see if I could use DLR's dynamic code generation do this without writing a new DLR language. It seemed like the support for the internal "Invariant" language might do the trick, but I've run into a few problems in my initial attempts. The idea is to use DLR to change the value of the Key property in a DictionaryEntry:

var runtime = ScriptRuntime.CreateFromConfiguration();
var ops = runtime.Operations;
var de = new DictionaryEntry("Key", "Value");
 
ops.SetMember(de, "Key", "Changed");  // Late-bound property set
Console.WriteLine(de.Key);

The call to CreateFromConfiguration() is failing complaining that "ScriptRuntimeSetup must have at least one LanguageSetup". OK, I can get around that with a dummy language:

class Foo { }
 
static void Main(string[] args)
{
    var setup = new ScriptRuntimeSetup();
    setup.LanguageSetups.Add(
        new LanguageSetup(typeof(Foo)
            .AssemblyQualifiedName, 
            "Foo language"));
    var  runtime = new ScriptRuntime(setup);
    var ops = runtime.Operations;
    DictionaryEntry de = new DictionaryEntry("Key", "Value");
    ops.SetMember(de, "Key", "Changed");  // Late-bound property set
    Console.WriteLine(de.Key);
}

The next problem seem harder, ops.SetMember() is throwing a NotImplementedException. Digging further, I've had to implement my own LanguageContext & DefaultBinder classes, and even when I get dynamic property get's working, the property set seems to be silently failing. Perhaps I've missed tomething fundamental.

A simple working example along the lines of the above would really help.

Read the full discussion online.

To add a post to this discussion, reply to this email (dlr@discussions.codeplex.com)

To start a new discussion for this project, email dlr@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com