Code Monkey home page Code Monkey logo

jint's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jint's Issues

support for .net enums

should enums be supported? The test fails.

I added the following test (in InteropTests.cs):

    [Fact]
    public void ShouldUseEnums()
    {
      RunTest(@"
            var Shapes = importNamespace('Shapes');
            var circle = Shapes.ShapeKind.CIRCLE_KIND;
            assert(circle === 10);
            var square = Shapes.ShapeKind.SQUARE_KIND;
            assert(square === 20);
        ");
    }

I changed Shapes.cs to (added an enum):

namespace Shapes
{
    public enum ShapeKind
    {
          CIRCLE_KIND = 10,
          SQUARE_KIND = 20
    }

...

It fails with the following exception:

System.Reflection.TargetInvocationException
Exception has been thrown by the target of an invocation.
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at System.Delegate.DynamicInvoke(Object[] args)
at Jint.Runtime.Interop.DelegateWrapper.Call(JsValue thisObject, JsValue[] arguments) in DelegateWrapper.cs: line 58
at Jint.Runtime.ExpressionInterpreter.EvaluateCallExpression(CallExpression callExpression) in ExpressionIntepreter.cs: line 869
at Jint.Engine.EvaluateExpression(Expression expression) in Engine.cs: line 442
at Jint.Runtime.StatementInterpreter.ExecuteExpressionStatement(ExpressionStatement expressionStatement) in StatementInterpreter.cs: line 32
at Jint.Engine.ExecuteStatement(Statement statement) in Engine.cs: line 373
at Jint.Runtime.StatementInterpreter.ExecuteStatement(Statement statement) in StatementInterpreter.cs: line 22
at Jint.Runtime.StatementInterpreter.ExecuteStatementList(IEnumerable`1 statementList) in StatementInterpreter.cs: line 417
at Jint.Runtime.StatementInterpreter.ExecuteProgram(Program program) in StatementInterpreter.cs: line 488
at Jint.Engine.Execute(Program program) in Engine.cs: line 313
at Jint.Engine.Execute(String source) in Engine.cs: line 300
at Jint.Tests.Runtime.InteropTests.RunTest(String source) in InteropTests.cs: line 30
at Jint.Tests.Runtime.InteropTests.ShouldUseEnums() in InteropTests.cs: line 492

Exception during method execution when parameter count does not match

Hi,

following code throws an error:

var engine = new Engine();
engine.SetValue("Put", (Action<string, object, object>)(Put));
engine.Execute("Put('1', { });");

private static void Put(string key, object value, object meta) { ... }

How can I solve this issue? It is pretty common in JS world to not pass all the parameters to the function. Same scenario was working in Jint 0.9.3.

Thanks for answer in advance,
P.

Event Handling, Howto?

Hello sebastienros,
How can I handle CLR events inside of JavaScript?
The old method doesnt work.

Implement type converters

Be able to provide converters by type. For instance in RavenDb, LoadDocument() can be called from scripts, and returns a RavenJObject. But as there is an existing wrapper for RavenJObject it should be used to be converted in JS. Ideally at the engine level we would register a Func<T, JsValue> for it.

Debugging

One of best feature of Jint was a debugger for scripts:

JintEngine engine = new JintEngine();
engine.SetDebugMode(true);

jint.Step += (sender, info) =>
{
   Console.WriteLine("{0}: Line {1}, Char {2}", info.CurrentStatement.ToString(), info.Location.Start.Line, info.Location.Start.Char);
};

But currently there no any out-of-box debugger (Jint.Debugger.DebugInformation) in Jint v.2 to get information about
a. Executed statement,
2. call stack,
3. local variables.

Add a LocalTimeZone option to the engine

Currently the local timezone for the engine is the local time from the machine. It would be nice to be able to set the "local" timezone for the engine to operate in.

Dotnet integration

Using the nuget package, this may have been fixed in git HEAD?

Constructors seem to be found, but some (not sure of the criteria)? methods are not

jint> System.DateTime.Now
=> "2014-06-01T02:16:30.698Z"
jint> System.DateTime.Now.ToString()
TypeError: Object has no method 'ToString'
jint> System.String('a',32)
=> "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
jint> System.String('a',32).LastIndexOf('a')
TypeError: Object has no method 'LastIndexOf'
jint> System.String('a',32).ToLower()
TypeError: Object has no method 'ToLower'

.NET params support

Hi Sebastien,
I'm adding .NET params support in my fork. Any chance it will be merged to the main branch when it will be done?

public class A {
  public string Call7(params object[] values) {
        return String.Join(",", values);
    }
[Fact]
public void ShouldCallInstanceMethodWithParams() {
    _engine.SetValue("a", new A());
    RunTest(@"assert(a.Call7('1','2','3') === '1,2,3');");
}

Swallowed exception when thrown in a C# method call from a C# object created by the JavaScript

Hi,

When my script calls a C# method that creates and returns a new C# object and then calls a method on this second object, if an exception occurs in that second call, the exception message is swallowed.

Run the attached NUnit tests to see. The second test fails.

The exception message is TypeError: No public methods with the specified arguments were found. instead of "something containing 'This is the real exception!'".

This makes debugging really hard, if not impossible. Could this be fixed so the actual exception message is visible somewhere?

Thanks.

using v2.1.0.0

public class JintTests
{
   [Test]
   public void JintRethrowSimpleException()
   {
      var engine = new Engine();

      engine.SetValue("testFct", new Action(() => { throw new ApplicationException("This is the real exception!"); }));

      try
      {
         engine.Execute(@"testFct();");
      }
      catch (Exception e)
      {
         Assert.That(e.ToString(), Contains.Substring("This is the real exception!"));
      }
   }

   [Test]
   public void JintRethrowException()
   {
      var engine = new Engine();

      var objA = new A();
      engine.SetValue("objA", objA);

      try
      {
         engine.Execute(@"
var objB = objA.getObjB();
objB.throwException();
");
      }
      catch (Exception e)
      {
         Assert.That(e.ToString(), Contains.Substring("This is the real exception!"));
      }
   }
}

public class A
{
   public B getObjB()
   {
      return new B();
   }
}

public class B
{
   public void throwException()
   {
      throw new ApplicationException("This is the real exception!");
   }
}

Performance Concerns

I have just started looking into Jint after having very poor performance with NLua with a project of mine. After implementing Jint in its place I am seeing similar results in performance though. I'm fairly certain this is due to the conversions between C# -> scripting engine and back.

My project consists of extending a plugin system to allow plugins to be written in a scripting language and not require compiling. This also allows for unloading/reloading of plugin scripts instead of having to hard-restart the server since .NET DLLs cannot be unloaded (unless they are ran in separate AppDomains etc.)

One of the tests I was using to check the performance is on the games Update call. This is called constantly as it is the games loop handler. From within my scripts callback for this handler, I loop the player list and do some checks and such on the objects like this:

function GameUpdate()
{
    for (var x = 0; x < SomeObject.SubArray.length - 1; x++) {
        if (SomeObject.SubArray[x] != undefined && SomeObject.SubArray[x].Active == true)
        {
            print(SomeObject.SubArray[x].Name);
        }
    }
}

SomeObject is a static object on the .NET side. Its SubArray is an array (255 static sized) array of another object type.

So in this case I am looping the 255 objects every frame of the server. If this is coded in C# itself, there is no performance drops noticeable. But with Jint, the game server is unplayable from the lag this produces.

(The lag is there even without the print, that was just to give an example. So it is not an output slowdown etc.)

My question would be is there something I am doing wrong or "bad" in a sense of how I am using Jint?
Is there a better method to approach this with to prevent the lag?

Error trying to use handlebars.js

Hello, I'm trying this code:

    [Theory]
    [InlineData("Handlebars", "http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.3.0.js")]
    public void HandlebarsTest(string name, string url)
    {
        var content = new WebClient().DownloadString(url);
        var engine = new Engine();
        engine.Execute(content);

        var testCode = @"
                            var source   = 'Hello {{name}}';
                            var template = Handlebars.compile(source);
                            var context = {name: 'Paul'};
                            var html = template(context);
                        ";

        engine.Execute(testCode);
    }

But I get this error:

int.Runtime.JavaScriptException
Parse error on line 1:
Hello {{name}}
--------------^
Expecting 'EOF', 'CONTENT', 'COMMENT', 'OPEN_BLOCK', 'OPEN_INVERSE', 'OPEN_ENDBLOCK', 'OPEN', 'OPEN_UNESCAPED', 'OPEN_PARTIAL', got '1'

What I'm doint wrong? If I execute a test like this in ClearScript with V8 engine, all works fine:

    [Theory]
    [InlineData("Handlebars", "http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.3.0.js")]
    public void ClearScriptV8Test(string name, string url)
    {
        var content = new WebClient().DownloadString(url);

        using (var runtime = new V8Runtime())
        {
            var script = runtime.Compile(content);
            var engine = runtime.CreateScriptEngine();
            engine.Evaluate(script);

            var testCode = @"
                            var source   = 'Hello {{name}}';
                            var template = Handlebars.compile(source);
                            var context = {name: 'Paul'};
                            var html = template(context);
                        ";

            engine.Execute(testCode);
            Assert.Equal("Hello Paul", engine.Script.html);
            engine.Dispose();
        }

    } 

Kind regards

direct access to .net enums not working

it seems jint cannot resolve MessageBoxButtons.YesNo or DialogResult.Yes

// requires:
// _engine = new Engine(cfg => cfg.AllowClr(typeof(System.Windows.Forms.MessageBox).Assembly));
//

// the following does not work because can not access enums
var winForms = importNamespace('System.Windows.Forms');

var message = "Hello from jint, press Yes to print a message";
var caption = "Jint Message Box";
var buttons = winForms.MessageBoxButtons.YesNo;

// Displays the MessageBox.

var result = winForms.MessageBox.Show(message, caption, buttons);

if(result == winForms.DialogResult.Yes)
{
print("pressed Yes");
}

// the following works
var winForms = importNamespace('System.Windows.Forms');

winForms.MessageBox.Show('Hello from jint - javascript');

Trying to overwrite variable throws

var engine = new Engine();
engine.SetValue("awesome", "Foo");
engine.SetValue("awesome", "Bar");

I'd expect this to overwrite the value of awesome, but instead it throws.

Can't execute simple function

Hello.

This is my code:
var jsEngine = new Jint.Engine();
jsEngine.Execute(rsaBiJs);
jsEngine.Execute(rsaJs);
jsEngine.SetValue("modStr", modStr);
jsEngine.SetValue("expStr", expStr);
jsEngine.SetValue("password", UserPassword);
jsEngine.Execute(@"var pubKey = RSA.getPublicKey( modStr, expStr );");
jsEngine.Execute(@"password = password.replace( /[^\x00-\x7F]/g, '' );");
jsEngine.Execute(@"var encryptedPassword = RSA.encrypt( password, pubKey );");
string encryptedPassword = jsEngine.GetValue("encryptedPassword").AsString();

Where:
rsaJs is string whitch contents this script: https://steamstore.map2.ssl.hwcdn.net/public/javascript/crypto/rsa.js

rsaBiJs:
https://steamstore.map2.ssl.hwcdn.net/public/javascript/crypto/jsbn.js

modStr and expStr are just strings. (Yes. Those have proper data in them).

It fails on this line:
jsEngine.Execute(rsaBiJs);

Compile for .NET Framework 3.5

I am trying to compile with the target framework .NET Framework 3.5 since the NuGet only supports 4.0 or higher.

It looks the JsValue.cs class is the only one with compiler errors.

using System.Diagnostics.Contracts;
using System.Dynamic;

After removing those imports I also removed the [Pure] attributes but the last thing was the ExpandoObject which appears to be part of the dynamic namespace. I replaced that with Dictionary<string,object> and so far so good.

Maybe consider adding support for 3.5? If not, then others can reference these changes.

Strange parsing of ending semicolon

Almost the same code gives different results (differ only in the location of semicolon):

namespace TestJint
{
    using System;
    using System.Threading;
    using System.Globalization;

    using Jint;

    class Program
    {
        static void Main(string[] args)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

            const string initData = "var engines = ['Chakra', 'V8', 'Jurassic', 'Jint'];";
            const string input1 = @"engines
    .filter(
        function (value, index, array) {
            return value.length > 5;
        })
    .toString()
    ;";
            const string input2 = @"engines
    .filter(
        function (value, index, array) {
            return value.length > 5;
        })
    .toString();";

            var jsEngine = new Engine();
            jsEngine.Execute(initData);

            string output1 = jsEngine.Execute(input1).GetCompletionValue().ToString();
            string output2 = jsEngine.Execute(input2).GetCompletionValue().ToString();

            Console.WriteLine("output1 = {0}", output1); // output1 = undefined
            Console.WriteLine("output2 = {0}", output2); // output2 = Chakra,Jurassic

            Console.ReadLine();
        }
    }
}

Calling .Net method with System.Action delegate argument from JS fails

Calling a .Net method which has an argument of type System.Action fails:

"No public methods with the specified arguments were found."

The function is defined as:

public void Setup(Action functionBlock)

and called from Javascript as:

hg.Program.Setup(function(){
    // ...
});

other methods which belong to hg.Program class work fine.

Module syntax (parenthesized function) gives TypeError

Attempting to use "module syntax" within Jint results in a TypeError. node compiles this code and runs it just fine.

            var engine = (new Engine((opts) => {}));

            engine.Execute(@"
                var c = 12;
                var a = function(q) { return q + c; }
                (function() {
                    var old = a;
                    a = function(q) {
                        return q;
                    }
                })();
            ");

            engine.Invoke("a", 3);
Jint.Runtime.JavaScriptException: 
  at Jint.Engine.Execute (Jint.Parser.Ast.Program) [0x0006c] in /Users/ed/Development/testbed/Dependencies/Jint/Jint/Engine.cs:243
  at Jint.Engine.Execute (string) [0x0000f] in /Users/ed/Development/testbed/Dependencies/Jint/Jint/Engine.cs:222

There's a workaround (assigning the function to a variable, invoking the variable) but it does pollute the scope so it's kind of sub-optimal. (Looking at this for a mod system in a game, so everyone would have to be sure not to re-var an existing value. That'd be tough.)

Great project - it's really a fantastic library. Thank you for your hard work!

Suggestion: special syntax to call .NET indexers

Current .NET indexers support in JINT is a bit messy.

  1. It doesn't support multi-argument indexers
  2. It's not strongly-typed (non-deterministic)
  • let's say there are this[DateTime date], this[string key] and this[int index]
  • there is javascript, clrObj['123'] = 'whatever'
  • which indexer will be invoked?
    3) There is a quite high risk that .NET indexer will mess up with some javascript object's own property

I our case we had to write proxies/wrappers with no indexers around all our .NET types being exposed to javascript, because we don't feel the current indexer implementation is safe. Looks like some special syntax to access .NET syntax would be more reliable rather than 'clrObj[index]', maybe something like clrObj.getItem(param1, param2...) and clrObj.setItem(param1, param2...)

Can't create CLR object

Hello,

I'm trying Jint and I can't figure out how to create a CLR object from Javascript. I'm trying to reproduce the example in the readme.md and it raises an exception No public methods with the specified arguments were found. :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Jint;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var engine = new Engine(cfg => cfg.AllowClr());
            engine.Execute(@"
                var file = new System.IO.File('log.txt');
                file.WriteLine('Hello World !');
                file.Dispose();
            ");
        }
    }
}

Could you please enlighten me as to what i'm missing ?

Thanks

Math.pow() throws non-Jint exception

Engine.Execute(Math.pow(2)) will throw a System.IndexOutOfRangeException.

My understanding is that no exception other than JavaScriptException and PaserError should be thrown by JINT, or an upper layer module has to use ‘catch (Exception)’ to handle unpredictable exceptions.

any plan to improve the jint performance?

jint is very cool . i have use it in my mobile project.
but simple tests show jint run about 100 slower than plain c# code at least.
i don't know why.
i have used lua. it is very fast even without jit.
any plan to improve the performance?

thank you for cool jint!

about static data member

Static data members of C# class can't be accessed in javascript.
Static property of C# class can't be set to new value.

Infinite loop

Hi Sébastien,

What do you think is the best way to prevent infinite loops? If we use this in our server code, we'd prefer a customer can't bring down the infrastructure simply because they wrote a loop that doesn't end :)

Any advice appreciated! Ideal situation would be something that we could instrument and adjust as necessary based on our trust of the code.

Great project by the way - hugely useful.

Steve

accessing indexer of a .NET object is not supported

I created in C# an object exposed as localeStorage in JavaScript.
The clear, setItem and getItem work great.
But calling my object like that localStorage['a1'], return null

localStorage.clear();
localStorage.setItem('a1', 1);
var v1 = localStorage.getItem('a1');
var v2 = localStorage['a1'];

I tried to update Jint\Runtime\Interop\ObjectWrapper .cs method
public override PropertyDescriptor GetOwnProperty(string propertyName)
and add at the end the following, knowing that an indexer Get is the method get_item.
It does not work but the solution should be close.

var indexerMethods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public)
.Where(m => m.Name == "get_Item").ToArray();
if (indexerMethods.Length > 0)
{
return new PropertyDescriptor(new MethodInfoFunctionInstance(Engine, indexerMethods), false, true, false);
}

Thanks.
Fred.

BindingFlags type converted to double when passed to GetField

BasicDoor is a UnityEngine class. This script code is running under Jint 0.9. Util.TryFindType passes the Type to an out variable, similar to Jint 2's importNamespace.

It looks as though Jint is casting my BindingFlags bitmap to a double. Is there a way to do this that avoids this problem? Is this handled differently in Jint 2?

var bdoor, sysref;
Util.TryFindType("System.Reflection.BindingFlags", sysref);
Util.TryFindType("BasicDoor", bdoor);
var state = bdoor.GetField("state", sysref.NonPublic | sysref.Instance); //this line gives error, "System.InvalidCastException: Value is not a convertible object: System.Double to System.Reflection.BindingFlags"
UnityEngine.Debug.Log("works");

StackOverflowException when running JSXTransformer

I'm trying to run Facebook's React JSX compiler in an ASP.NET MVC library via Jint but am encountering a stack overflow.

Here's a repro:

// From http://facebook.github.io/react/js/JSXTransformer.js
var jsxTransformerCode = File.ReadAllText("JSXTransformer.js"); 

var input = @"
/** @jsx React.DOM */
var HelloWorld = React.createClass({
    render: function () {
        return (
            <div className=""awesome"">
                Hello {this.props.name}
            </div>
        );
    }
});";
var encodedInput = JsonConvert.SerializeObject(input);
var code = "global.JSXTransformer.transform(" + encodedInput + ").code";

var engine = new Engine();
engine.Execute("var global = {};");
engine.Execute(jsxTransformerCode);
var result = engine.Execute(code).GetCompletionValue().ToObject();
Console.WriteLine(result);

And the associated stack trace: https://gist.github.com/Daniel15/9594581

This does work with IE's engine via MsieJavaScriptEngine but I'm trying to create something that will work in Mono.

Get all CLR exceptions result from .Net invoking in JavaScript code wrapped in a new exception

If CLR option is enabled, all CLR exceptions result from .Net invoking in JavaScript code are wrapped in a new type of exception, such as ‘CLRException’ or the like; otherwise, no CLRException will be raised. Finally this ‘CLRException’ is re-wrapped in JavascriptException and thrown to the end caller.

When user turning on CLR in Jint, he or she can check ‘InnerException’ of JavascriptException to see if it is actually a ‘CLRException’. I think we cannot simply use generic JavascriptException instead of ‘CLRException’ for this.

For an example:
try {
xEngine.Execute(@“var sFileName=’NonExistence’;var data=System.IO.File.ReadAllText(sFileName)”);
}
Catch(JavascriptException jexp)
{
If (jexp.InnerException is CLRException)
{
If (CLRException.InnerException is FileNotFoundException)
Console.WriteLine (“The file does not exist.”); //We know now what exactly happened
Else Console.WriteLine (jexp.InnerException.Message);
}
Else Console.WriteLine (jexp.Message);
}

Jint throws error when attempting to add event handler to System.Windows.Forms.Timer

Not sure if there is a "new" way of doing this but...

The following code throws: "TypeError: No public methods with the specified arguments were found."

when calling timer.add_Tick(doit);

Note: this worked in the previous version (0.9.2) of Jint.

var winForms = importNamespace('System.Windows.Forms');

function doit()
{
print("timer fired");
}

var timer = new winForms.Timer();
timer.add_Tick(doit);

timer.Interval = 1000;
timer.Start();

Collisions with overload resolution

Hi Sebastien,

First of all, thank you man for a great project!

The big issue I see so far is .NET method overload resolution collisions. Overloads with different arguments number are resolved fine, but the ones which have the same number of arguments of different types become royal pain in the ass really.
As far as I can see from TypeConverter.FindBestMatch and MethodInfoFunctionInstance.Invoke implementations, it simply iterates through the overloads trying to convert every single argument to desired argument type, and invokes the first overload where all arguments are converted successfully. This basically means that if I have two overloads with the same arguments length, I can't really be sure which one will be called unless I make converter to be very strict. This also means that I can't have overloads (like F(object) and F(string)) and pass null to it because it simply fails in FindBestMatch method when trying to read argument type. At the same time real C# compiler resolves such overloads properly through scanning class tree.

Do you have any plans for handling that? If not, could you share your thoughts/ideas on what is the best way to solve that?

PS: In the end of FindBestMatch method there is a totally redundant loop through methods doing actually nothing. Probably just some copy-paste trash left, but still it strikes the performance greatly...

Sum of two float values returns a NaN

Hello!

Following code prints to console result = NaN:

namespace TestJint
{
    using System;

    using Jint;
    using Jint.Native;

    class Program
    {
        static void Main(string[] args)
        {
            var jsEngine = new Engine();
            JsValue resultValue = jsEngine.Execute("2.5 + 12.7").GetCompletionValue();
            double result = resultValue.AsNumber();

            Console.WriteLine("result = " + result); // result = NaN
            Console.ReadLine();
        }
    }
}

string.replace() not working

I believe this might be the same problem described in #50.

I am using jint to test some logic in both c# and JavaScript and discovered this in one of my unit tests. Here is my code:

    public class Replace3WithAAnd5WithBChallenge
        : IChallenge
    {
        public string ChallengeInJavaScript()
        {
            var sb = new StringBuilder();
            sb.AppendLine("function Challenge(value) {");
            sb.AppendLine("  var temp = value.replace('3', 'A');");
            sb.AppendLine("  var temp2 = temp.replace('5', 'B');");
            sb.AppendLine("  return temp2;");
            sb.AppendLine("}");
            return sb.ToString();
        }

        public string Challenge(string value)
        {
            return value.Replace("3", "A").Replace("5", "B");
        }
    }

        [Test]
        public void Challenge_ChallengeInJavascript_WithRandomValue_ShouldReturnSameResult()
        {
            // arrange
            var executor = new JavaScriptFunctionExecutor();
            var target = new Replace3WithAAnd5WithBChallenge();
            var value = Guid.NewGuid().ToString();

            // act
            var result1 = executor.ExecuteFunction(target.ChallengeInJavaScript, value);
            var result2 = target.Challenge(value);

            // assert
            var actual = result1;
            var expected = result2;
            Assert.AreEqual(expected, actual);
        }

    public class JavaScriptFunctionExecutor
    {
        public string ExecuteFunction(Func<string> function, string value)
        {
            var js = function();
            var engine = new Engine()
                .Execute(js);

            var result = engine.Invoke("Challenge", value);

            return result.ToString();
        }
    }

I tested the JavaScript in Chrome and it works fine, but running it through jint, the values are not replaced as expected.

I also tried replacing the single quotes with double quotes, but the problem persists.

regular expression new RegExp('/') is not correctly handled

The regular expression '/' become ''

Seel file D:\DVT\jint\Jint\Native\RegExp\RegExpConstructor.cs
method: public ObjectInstance Construct(JsValue[] arguments);
line: p = pattern != Undefined.Instance ? TypeConverter.ToString(pattern).Trim('/') : "";

Separate the parser & interpreter

I'd like to propose separating the parser infrastructure that was ported over from Esprima from the interpreter that's been built on top in Jint, for the following reasons:

  • The parser can be used as shared infrastructure by the .NET community (much like the Esprima) to write other JavaScript-related tools, including experimentation in compilers and interpreters.
  • The parser and interpreter can evolve independently & have separate release cycles, issue tracking and so on.
  • It would give Jint more focus on just the runtime and execution bits.

I have forked a new project called Escape that hosts just the parser bits and pushed it out as a NuGet package. Apart from the namespace change, I've kept the public API source-compatible deliberately so it can be linked back into Jint with minimal effort (the parser API needs some clean-up going forward so I wanted to make a 1.0 release before going forward). In fact, I've even attempted to do that in a local & would be happy to submit a PR if you like the idea.

IConvertible requirement

Hi again. Apologies for the endless questions.

We have some code where we basically want to perform operations on a "state" object through JavaScript. What we do is pass the state object in and then use the static Action implementations to manipulate the object. However, since doing the latest repository update, we're getting an "Object must implement IConvertible" on our StateWrapper object.

Here's the code that replicates the issue (below).

At the moment we call a method we've added: "setStringValue(state, "the value") - with the state parameter being our StateWrapper. Our ideal implementation would actually be: state.setString("the value"), but that's something we'll need to figure out.

Any help appreciated. Not sure if this is an issue, however, the code did work, and now it doesn't so figured I'd submit it in!

Cheers,

Steve

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Jint;
using Jint.Native;
using Jint.Parser;
using Jint.Runtime;
using Jint.Runtime.Interop;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Engine engine = null;
            JsValue jsValue;

            engine = new Engine(cfg => cfg.MaxStatements(5000));
            engine.SetValue("state", new StateWrapper());

            // Create the set commands
            engine.SetValue("setStringValue", new Action(StateProxy.SetStateValueString));
            engine.SetValue("setNumberValue", new Action(StateProxy.SetStateValueNumber));
            engine.SetValue("setDateTimeValue", new Action(StateProxy.SetStateValueDateTime));
            engine.SetValue("setBooleanValue", new Action(StateProxy.SetStateValueBoolean));
            engine.SetValue("setPasswordValue", new Action(StateProxy.SetStateValuePassword));

            // Create the get commands
            engine.SetValue("getStringValue", new Func(StateProxy.GetStateValueString));
            engine.SetValue("getNumberValue", new Func(StateProxy.GetStateValueNumber));
            engine.SetValue("getDateTimeValue", new Func(StateProxy.GetStateValueDateTime));
            engine.SetValue("getBooleanValue", new Func(StateProxy.GetStateValueBoolean));
            engine.SetValue("getPasswordValue", new Func(StateProxy.GetStateValuePassword));

            // Execute the macro as defined by the element
            jsValue = engine.Execute(@"function hello() { 
                    while(true) {
                        setStringValue(state, ""{![Blah]}"", ""yadda yadda""); 
                    }
                }

                hello();");
        }
    }

    public class StateProxy
    {
        public static void SetStateValueString(Object stateObject, String valueElementReference, String contentValue)
        {

        }

        public static void SetStateValueNumber(Object stateObject, String valueElementReference, Double contentValue)
        {

        }

        public static void SetStateValueDateTime(Object stateObject, String valueElementReference, DateTime contentValue)
        {

        }

        public static void SetStateValueBoolean(Object stateObject, String valueElementReference, Boolean contentValue)
        {

        }

        public static void SetStateValuePassword(Object stateObject, String valueElementReference, String contentValue)
        {

        }

        public static String GetStateValueString(Object stateObject, String valueElementReference)
        {
            return "string";
        }

        public static Double GetStateValueNumber(Object stateObject, String valueElementReference)
        {
            return 0;
        }

        public static DateTime GetStateValueDateTime(Object stateObject, String valueElementReference)
        {
            return DateTime.MinValue;
        }

        public static Boolean GetStateValueBoolean(Object stateObject, String valueElementReference)
        {
            return false;
        }

        public static String GetStateValuePassword(Object stateObject, String valueElementReference)
        {
            return "password";
        }
    }

    public class StateWrapper
    {
        public String FlowImplementation
        {
            get;
            set;
        }

        public String State
        {
            get;
            set;
        }

        public String AuthenticatedUser
        {
            get;
            set;
        }
    }
}

Esprima Parse Tree

Does jint expose the Esprima parse tree?
The credits file says:

Jint contains a C# port of the Esprima Javascript parser.

If not where in the source can I find Esprima? I am interested in finding tokens in a script such as the following:

function getTokens(scriptString) {
    var parseTree = esprima.parse(scriptString, { tokens: true });
    return parseTree.tokens;
}

Can you point me in the right direction?

Error resolving a dynamic type object field.

When referencing a property of an object, obtained from calling a .Net method that returns a dynamic, the following error is raised:

Object reference not set to an instance of an object
at Jint.Runtime.TypeConverter+d__5.MoveNext () [0x00000] in :0 
at System.Collections.Generic.List`1[System.Reflection.MethodBase].AddEnumerable (IEnumerable`1 enumerable) [0x00000] in :0 
at System.Collections.Generic.List`1[System.Reflection.MethodBase]..ctor (IEnumerable`1 collection) [0x00000] in :0 
at System.Linq.Enumerable.ToList[MethodBase] (IEnumerable`1 source) [0x00000] in :0 
at Jint.Runtime.Interop.MethodInfoFunctionInstance.Invoke (System.Reflection.MethodInfo[] methodInfos, JsValue thisObject, Jint.Native.JsValue[] arguments) [0x00000] in :0 
at Jint.Runtime.Interop.MethodInfoFunctionInstance.Call (JsValue thisObject, Jint.Native.JsValue[] arguments) [0x00000] in :0 
at Jint.Runtime.ExpressionInterpreter.EvaluateCallExpression (Jint.Parser.Ast.CallExpression callExpression) [0x00000] in :0 
at Jint.Engine.EvaluateExpression (Jint.Parser.Ast.Expression expression) [0x00000] in :0 
at Jint.Runtime.StatementInterpreter.ExecuteExpressionStatement (Jint.Parser.Ast.ExpressionStatement expressionStatement) [0x00000] in :0 
at Jint.Engine.ExecuteStatement (Jint.Parser.Ast.Statement statement) [0x00000] in :0 
at Jint.Runtime.StatementInterpreter.ExecuteStatement (Jint.Parser.Ast.Statement statement) [0x00000] in :0 
at Jint.Runtime.StatementInterpreter.ExecuteStatementList (IEnumerable`1 statementList) [0x00000] in :0 
at Jint.Runtime.StatementInterpreter.ExecuteProgram (Jint.Parser.Ast.Program program) [0x00000] in :0 
at Jint.Engine.Execute (Jint.Parser.Ast.Program program) [0x00000] in :0 
at Jint.Engine.Execute (System.String source) [0x00000] in :0 

field in C# class are not accesible, property are

In the example the field LastName2 cannot be access and return undefined.
public class Foo
{
public string LastName1 { get; set; }
public string LastName2;

    public Foo()
    {
        this.LastName1 = "Torres";
        this.LastName2 = "Torres";
    }
}

var source = @"
var FredUnitTests = importNamespace('FredUnitTests');
var f = new FredUnitTests.Foo();
f.LastName1 + ' ' + f.LastName2;
";
var text = base.Execute(source);

What happened to return values?

In a previous release, we could merely do

object result = new JintEngine().Run("return 42;");

Now it seems we need to have all kinds of extra stuff and do

object result = new Jint.Engine().
Execute("function hello() { return 42; }; hello();").GetCompletionValue();

The biggest issue is that deciding what the name 'hello' should be, is problematic because the javascript code in the string may define the same name by accident and create infinite recursion.

We need the simple Run() behavior back so that we can get values out of scripts trivially.

"A numeric comparison was attempted on "$(TargetPlatformVersion)"" project error

Not sure if it's a Jint issue or an issue with my environment, but I'm getting this error when trying to open the Jint solution using Visual Studio 2013:

A numeric comparison was attempted on "$(TargetPlatformVersion)" that evaluates to "" instead of a number, in condition "'$(TargetPlatformVersion)' > '8.0'"

I searched around and some people reported getting this with ReSharper 8.2. I'm only on ReSharper 8.1 so I don't think that's the same issue.

Edit: msbuild jint.sln works fine so I'm using that to build

Multiple indexers on the same type lead to AmbiguousMatchException

Hi Sebastien,

If .NET object has multiple indexers, property evaluation fails with AmbiguousMatchException.
I mean something like this:

public class My
{

    public string this[int index]
    {
        get { return null; }
    }

    public string this[string index]
    {
        get { return null; }
    }
}

        var engine = new Engine();
        engine.SetValue("$", new My());
        engine.Execute("var s = $[1];");

Basically this can be fixed in IndexDescriptor to enumerate all indexers and invoke first successful one (same as it's done for method overload resolution now). But it really leads to collisions hell... :(

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.