Are there any .NET CLR/DLR implementations of ECMA

2019-01-21 01:47发布

Does anyone know of real (i.. no vaporware) implementations of ECMAScript targeting the .NET CLR/DLR? Ideally something like what Rhino is for Java. A solid port of Rhino running on .NET Framework / Mono Framework would be perfect.

I've only seen a handful of projects mentioned but never seen any come to light or in reality anything that I've ever been able to run script on. Here's what I know about already:

  • MSScriptControl ActiveX Control: AFAIK, this was Microsoft's last real ECMAScript-compliant implementaiton (runs JScript 5.7). I've integrated with MSScriptControl but don't consider COM interop to be an answer to this question. x64 is a killer for this option.

  • JScript.NET: I don't count JScript.NET as it could never successfully parse any of my real scripts. It seems to have trouble with closures.

  • Managed JScript: Sounds like what I want but it appears to be dead in the water. It was a major example implementation for the DLR but then got entangled with SilverLight and seems to have faded as a priority since 2007. Creditable sources on the status of this would be helpful.

  • MyJScript: Built as a tutorial implementation for the DLR. Anyone know how complete of an implementation this is?

  • Jint: JavaScript interpreter for .NET. Doesn't as of yet support Currying or try-catch-finally.

  • RemObjects Script for .NET: An interesting contender still in the works. I'm confused by their marketing as to what it will actually be, but it sounds like it might eventually be a fit. If anyone knows more about it that would be helpful as well.

  • V8 for .NET: This would be great if someone ported V8 to .NET. As far as I know there isn't a large effort around this either. The link is to an idea for calling into it from a managed C++ wrapper.

For background, I want to be able to execute JavaScript from within .NET; i.e. load up a set of scripts into context and call into that context and retrieve the execution results. Currently I jump through hoops to use MSScriptControl via cumbersome COM Interop. The inconsistency of COM makes it really tough for deployment and ensuring consistent execution.

I'd like to be able to execute reasonably complex JavaScript test harnesses from within .NET. This isn't for creating user macros or simple tiny scripts; I need a real JavaScript environment like Rhino. If the implementation was running on top of the CLR (rather than COM) this would really help with some of the current issues.

9条回答
兄弟一词,经得起流年.
2楼-- · 2019-01-21 02:31

Still Roughly alive:

  • Jurassic (Had a commit within the last year.)
  • Jint (currently taking pull requests.)

Other Projects, Mostly Dead:

Crazy Method:

  • Rhino over IKVM (Mentioned in comments, but here's a link to more information about doing it.)
查看更多
干净又极端
3楼-- · 2019-01-21 02:33

Nobody has mentioned jurassic http://jurassic.codeplex.com/ I do not know how good it is in general (performance, usability, etc) but at least it parses pretty complex scripts (other implementations do not) and it supports ECMAScript 5 spec. I just add the link here for reference.

查看更多
Viruses.
4楼-- · 2019-01-21 02:34

Nobody's mentioned ClearScript, so ClearScript.

It's not an implementation; it's an interop wrapper that supports V8, JScript and VBScript, with a really nice API to call into them from .NET code.

Example code from the CodePlex page:

using System;
using Microsoft.ClearScript;
using Microsoft.ClearScript.V8;

// create a script engine
using (var engine = new V8ScriptEngine())
{
    // expose a host type
    engine.AddHostType("Console", typeof(Console));
    engine.Execute("Console.WriteLine('{0} is an interesting number.', Math.PI)");

    // expose a host object
    engine.AddHostObject("random", new Random());
    engine.Execute("Console.WriteLine(random.NextDouble())");

    // expose entire assemblies
    engine.AddHostObject("lib", new HostTypeCollection("mscorlib", "System.Core"));
    engine.Execute("Console.WriteLine(lib.System.DateTime.Now)");

    // create a host object from script
    engine.Execute(@"
        birthday = new lib.System.DateTime(2007, 5, 22);
        Console.WriteLine(birthday.ToLongDateString());
    ");

    // use a generic class from script
    engine.Execute(@"
        Dictionary = lib.System.Collections.Generic.Dictionary;
        dict = new Dictionary(lib.System.String, lib.System.Int32);
        dict.Add('foo', 123);
    ");

    // call a host method with an output parameter
    engine.AddHostObject("host", new HostFunctions());
    engine.Execute(@"
        intVar = host.newVar(lib.System.Int32);
        found = dict.TryGetValue('foo', intVar.out);
        Console.WriteLine('{0} {1}', found, intVar);
    ");

    // create and populate a host array
    engine.Execute(@"
        numbers = host.newArr(lib.System.Int32, 20);
        for (var i = 0; i < numbers.Length; i++) { numbers[i] = i; }
        Console.WriteLine(lib.System.String.Join(', ', numbers));
    ");

    // create a script delegate
    engine.Execute(@"
        Filter = lib.System.Func(lib.System.Int32, lib.System.Boolean);
        oddFilter = new Filter(function(value) {
            return (value & 1) ? true : false;
        });
    ");

    // use LINQ from script
    engine.Execute(@"
        oddNumbers = numbers.Where(oddFilter);
        Console.WriteLine(lib.System.String.Join(', ', oddNumbers));
    ");

    // call a script function
    engine.Execute("function print(x) { Console.WriteLine(x); }");
    engine.Script.print(DateTime.Now.DayOfWeek);

    // examine a script object
    engine.Execute("person = { name: 'Fred', age: 5 }");
    Console.WriteLine(engine.Script.person.name);
}
查看更多
登录 后发表回答