Question about using CallSites in dynamic languages.

Nov 16, 2014 at 8:54 AM
Edited Nov 16, 2014 at 9:11 AM
Good day. I am currently working on a dynamic language implementation that requires the use of the "CompileToMethod" function of LambdaExpression.

I understand when creating the new type (TypeBuilder). My compiler also needs to generate CallSite<>'s and define them. Which it can do.

The problem I have come to face is when using 2 dynamic binders in conjunction with each other. Specifically I have a ConvertBinder that is responsible for a lot of dynamic conversions throughout my expression code. When I went to refactor my implementation to consider it might be compiled with the knowledge of a TypeBuilder (to create the static fields). I noticed that it would be difficult for a binder that used the convert binder (an InvokeBinder for instance) to generate CallSites inside the context of it's appropriate 'Fallback' function without first knowing about the TypeBuilder that it's defining fields on. This is a problem because the type will most surely be created if a reference of that TypeBuilder is (somehow) passed to the binder.

My main question then is: How does an InvokeBinder (Example) create a callsite to a ConvertBinder (Actual Problem) while inside the "FallbackInvoke" function of it's binding process.
My first thought was just wrap the child binder in a lambda, but function calls would look (I'm guessing) like SomeFunction(() => { }, () => { }) where the results of the lambda was the type of the conversion, which would be a little inefficient wouldn't it?

Is there a proper way to allow binding in this way or do I need to circumvent it before the binding stage? Basically everything works fine as long as all the binders are created in advance. As soon as one binder tries to create another binder while it's falling back. thats when I run into issues.

Edit: I believe it could be possible for the (Invoke)binder to generate it's own callsite container class at runtime (it has access to the dynamic Module) but my initial thoughts would be that it would generate a new class every time "FallbackInvoke" executed. Which is also does not feel like an optimal scenario.
Nov 17, 2014 at 1:04 AM
Okay. I guess a good followup question would be, since it's kind of hard to case-test this in an incomplete language, is it safe to invoke dynamic binders inside the fallbacks.

When using CompileToMethod, when it encounters a DynamicExpression it throw an exception. The solution was to generate the callsite as a static field. Does that apply to ALL DynamicExpression nodes in the entire tree? OR just the callsite. I can implement it so child tree nodes just compile normally.

Example:

protected override void FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) {
// If I make a DynamicExpression here, does it need to be a CallSite<> ?
// Or since it's inside the context of a delegate, is it considered "Live" ?
}

Sorry I have been working in the DLR for some time now. However following the logic process can boggle my head from time to time.