Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS Function => CLR Delegate #37

Closed
dahlbyk opened this issue Apr 25, 2011 · 3 comments
Closed

JS Function => CLR Delegate #37

dahlbyk opened this issue Apr 25, 2011 · 3 comments
Assignees
Milestone

Comments

@dahlbyk
Copy link

dahlbyk commented Apr 25, 2011

With IronPython, I can do this:

var script = @"
def inc(x):
    return x+1
";
var pythonEngine = Python.CreateEngine();
var scope = pythonEngine.CreateScope();
pythonEngine.Execute(script, scope);
var inc = (Func<int, int>)scope.GetVariable("inc");
var three = inc(2);

I'm trying to do something similar with IronJS:

var script = @"
function inc(x) {
    return x+1;
}
";
var context = new IronJS.Hosting.CSharp.Context();
context.Execute(script);
var inc = context.GetGlobalAs<Func<int, int>>("inc");
var three = inc(2);

However, I get the following exception:

System.InvalidCastException: Unable to cast object of type 'IronJS.FunctionObject' to type 'System.Func`2[System.Int32,System.Int32]'.
at Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions.UnboxGeneric[T](Object source)
at IronJS.Hosting.CSharp.Context.GetGlobalAs[a](String name)

Is there a better way to export script as an executable delegate? Or if not, is this something you think IronJS could/should support? I'd be glad to help, but am unsure exactly where to start...maybe TypeConverter.ConvertTo()?

@fholm
Copy link
Owner

fholm commented Apr 25, 2011

Yes there is a way to get a JS function as a CLR delegate, it's currently a bit clunky as it doesn't masqurade the internal parameters or return types and they get exposed to the hosting code, but here's the snippet:

var ctx = new IronJS.Hosting.CSharp.Context();

ctx.Execute(@"
    function multiply(a, b) {
        return a * b;
    }
");


var multiply = ctx.GetGlobalAs<FunctionObject>("multiply");
var delegate_ = multiply.MetaData.GetDelegate<Func<FunctionObject, CommonObject, double, double, BoxedValue>>(multiply);
var result = delegate_.Invoke(multiply, ctx.Globals, 4.0, 4.0).ClrBoxed;

I'll still mark this ticket as "missing feature" because we want to return a delegate that doesn't expose the internal stuff.

@ghost ghost assigned fholm Apr 25, 2011
@fholm
Copy link
Owner

fholm commented Apr 25, 2011

This if fixed in commit a6aecac0cb4 by adding a new function to the Hosting.CSharp.Context object (C#) and the Hosting.FSharp module called GetFunctionAs(name) / getFunctionAs<'a> name.

var ctx = new IronJS.Hosting.CSharp.Context();

ctx.Execute(@"
    function multiply(a, b) {
        return a * b;
    }
");


var multiply = ctx.GetFunctionAs<Func<double, double, double>>("multiply");
var result = multiply.Invoke(4.0, 4.0);

@fholm fholm closed this as completed Apr 25, 2011
@dahlbyk
Copy link
Author

dahlbyk commented Apr 28, 2011

Haven't had a chance to try it yet, but thanks for the quick response on this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants