Giter VIP home page Giter VIP logo

yantra's Introduction

YantraJS

Yantra (Machine in Sanskrit) is a Managed JavaScript Engine for .NET Standard written completely in C#.

NuGet

Name Package
YantraJS (With CSX Module Support) NuGet
YantraJS.Core (Compiler) NuGet
YantraJS.ExpressionCompiler (IL Compiler) NuGet
Yantra JS.ModuleExtensions (Fluent interface for module registration) Nuget

Features

  1. Compiles JavaScript to .Net Assembly
  2. Strict Mode Only JavaScript*
  3. Arrow functions
  4. Classes
  5. Class members
  6. Enhanced object literals
  7. Template strings and tagged templates
  8. Destructuring
  9. let const
  10. Map, Set, WeakMap, WeakSet
  11. Symbols
  12. Subclassable built-ins
  13. Binary and Octal literals
  14. Module support
  15. Null coalesce
  16. Optional property chain identifier?.[], identifier?.(, identifier?.identifier
  17. Rest, Default and Spread Parameters
  18. Generators, iterators, for..of
  19. Async/Await
  20. Optional parameters
  21. Tail call optimization
  22. Many ES5 + ES6 features
  23. CommonJS & ES6 Module Support
  24. Easily marshal CLR Object to JavaScript and other way around
  25. CSX Module support
  26. Mixed module system, YantraJS supports require and import.
  27. Explicit resource management with using and await using keywords.

* Most JavaScript today is available in strict mode, we do not feel any need to support non strict mode as modules are strict by default.

Mixed modules

Currently YantraJS supports Both CommonJS and ES modules without any extra work, with little trick, module resolution is node like. Module loader loads module asynchronously, so import will work without any extra effort. However, require will run AsyncPump to wait till the module is loaded correctly. Unless you do some multithreading, mixed modules will not lead to any deadlocks.

Module loading order,

  • Module names may or may not have extensions.
  • File will be loaded if same name exists on disk.
  • Engine will try to load ${name}.csx file, if it exists it will load the module.
  • Engine will then try to load ${name}.js file, if it exits it will load the module.
  • Otherwise it will travel to parent directory and search modules in node_modules folder in exact same order defined earlier.

Roadmap

As we often have difficulty in writing cross environment scripts (browser and process such as node), we want to first implement basic common features on both.

  1. Generate Runtime with Source Generator, this will allow us to load Yantra in AOT environment. Currently Runtime objects are loaded through reflection, however we are moving reflection code to Source Generator one class a at a time.
  2. Next in plan is Network API, Simple fetch is available in YantraContext, we will focus on adding Stream API.
  3. Next is File API, we will implement FileSytem of Web Browser API and allow an easy native interface. So you can write script that will execute correctly in browser and in native
  4. V8 Protocol Implementation is in progress.

Documentation

  1. Introduction
  2. Expression Compiler
  3. JavaScript Engine

Discussions

We recommend using Github Discussion on this repository for any question regarding this product.

Special Thanks

  1. We are thankful to authors of Jurassic (we have incorporated number parser, promise and some unit tests from Jurassic.) https://github.com/paulbartrum/jurassic
  2. We are thankful to authors of EsprimaDotNet, we initially built prototype over EsprimaDotNet, but we chose to build our parser/scanner from scratch to support token spans. https://github.com/sebastienros/esprima-dotnet
  3. We are thankful to author of ILPack (we have incorporated saving IL to Assembly from this library.) https://github.com/Lokad/ILPack

yantra's People

Contributors

ackava avatar dependabot[bot] avatar khareshubham avatar lahma avatar simmikava avatar taritsyn avatar zverguy avatar

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

yantra's Issues

Create closure of object/array literal

Constructing object/array literals eat up significant time, to improve speed, we can lift such literals out side of function, thus by creating a closure, will remove need of initialization. And instances will be kept alive as long as the function capturing them is alive.

  • The literal should not be returned
  • It should not be modified in the scope of the function

StringTests.cs - Concat()

        //Not working as on 11/23/2020 - Should work!!!
        //Assert.AreEqual("first", Evaluate(@"
        //    obj1 = { toString: function() { throw 'first' } };
        //    obj2 = { toString: function() { throw 'second' } };
        //    obj1.concat = String.prototype.concat;
        //    try {
        //        obj1.concat(obj2);
        //    }
        //    catch (e) {
        //        e;
        //    }"));

Actual Result:
Assert.AreEqual failed. Expected:<first (System.String)>. Actual:<[object Object] (YantraJS.Core.JSError)>
Expected: first

Expression Test.cs - Doesn't work in strict mode the below TC - Delete - as we are not supporting yet

// Deleting variables defined within an eval statement inside a global scope succeeds.
//Assert.AreEqual(true, Evaluate("abcdefg = 1; delete abcdefg"));
//Assert.AreEqual(false, Evaluate("abcdefg = 1; delete abcdefg; this.hasOwnProperty('abcdefg')"));
//Assert.AreEqual("ReferenceError", EvaluateExceptionType("x = 5; delete x; x"));

        // Deleting variables defined within an eval statement inside a function scope succeeds.
        //Assert.AreEqual(true, Evaluate("(function() { var a = 5; return eval('var b = a; delete b'); })()"));
        //Assert.AreEqual(true, Evaluate("b = 1; (function() { var a = 5; eval('var b = a'); return delete b; })()"));
        //Assert.AreEqual(1, Evaluate("b = 1; (function() { var a = 5; eval('var b = a'); delete b; })(); b;"));
        //Assert.AreEqual(1, Evaluate("b = 1; (function() { var a = 5; eval('var b = a'); delete b; return b; })()"));

How to pass ClrType to module for create instance in script

Hello again
i am trying to implement "moduleBuilder" like jint

   _context.RegisterModule("test", builder =>
            {
                builder.ExportType<TestClass>()
                    .ExportFunction("testFunc", TestMethod);
            } );

And when i try to create TestClass instance

 var barfromclass = await _context
                .RunScriptAsync("import {TestClass} from \"test\"\n export default new TestClass();",
                    String.Empty) as JSObject; 
            Assert.AreEqual("bar", barfromclass["Foo"].InvokeFunction(new Arguments()));

I am get exception

YantraJS.Core.JSException: undefined is not a function 

TestClass implementation

 public class TestClass
    {
        public string Foo() => "bar";
    }

ModuleBuilder implementation

public class ModuleBuilder
{
    private readonly KeyString _moduleName;
    private readonly JSModuleContext _moduleContext;
    private readonly JSObject _exportobj;

    internal ModuleBuilder(KeyString moduleName,JSModuleContext moduleContext)
    {
        _moduleName = moduleName;
        _moduleContext = moduleContext;
        _exportobj = new JSObject();
    }

    public ModuleBuilder ExportType<T>()
    {
        string name = typeof(T).Name;
        var type = ClrType.From(typeof(T));
        _exportobj[name] = type;
        return this;
    }

    public ModuleBuilder ExportValue(in KeyString name, object value)
    {
        _exportobj[name] = value.Marshal();
        return this;
    }

    public ModuleBuilder ExportFunction(in KeyString name, JSFunctionDelegate func)
    {
        _exportobj[name] = new JSFunction(func);
        return this;
    }

    internal void Build()
    {
        _moduleContext.RegisterModule(_moduleName, _exportobj);
    }

/// in JSModuleContext

 public void RegisterModule(in KeyString name, Action<ModuleBuilder> builder)
        {
            var modulebuilder = new ModuleBuilder(name ,this);
            builder.Invoke(modulebuilder);
            modulebuilder.Build();
        }

Maybe you can help what i do wrong?

upd some intresting information

ClrType return function() { [clr-native]}

изображение

On runing this return a VoidValueTask
изображение

When i call testFunc() this is called but dont return value

var barfromclass = await _context
                .RunScriptAsync("import {testFunc} from \"test\"\n export default testFunc();",
                    String.Empty);

изображение
изображение

Importing CLR Module Throws Null Reference Exception

I was trying to figure out how to import and use the clr module within JavaScript but I am getting an null reference exception.

                var context = new JSModuleContext();
                var r = context.Eval("import clr from \"clr\"");

box expression is bad

i want to return an int as object in my function, but i got several false results

YConstantExpression yconstant0 = new YConstantExpression(0, typeof(int));
YExpression.TypeAs(YExpression.Box(yconstant0), typeof(object)) // Fatal error. System.AccessViolationException: Attempted to read or write protected memory.
YExpression.Convert(YExpression.Box(yconstant0), typeof(object)) // Fatal error. System.AccessViolationException: Attempted to read or write protected memory.
YExpression.Convert(YExpression.Box(yconstant0), typeof(object), true) // Fatal error. System.AccessViolationException: Attempted to read or write protected memory.
YExpression.TypeAs(yconstant0, typeof(object)) // Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
YExpression.Convert(yconstant0, typeof(object)) // Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
YExpression.Convert(yconstant0, typeof(object), true) // got a null object
YExpression.Box(yconstant0) // Fatal error. System.AccessViolationException: Attempted to read or write protected memory.

os: win10 x64
dotnet: net6.0 x64
code:

static Func<int, object> TestFib()
{
    var ymethod = YExpression.Lambda<Func<int, object>>(
        "ymethod",
        YExpression.Condition(
            // if (n < 2)
            ynParamI0 < yconstant2,
            // return n;
            // YExpression.TypeAs(YExpression.Box(ynParamI0), typeof(object)),
            // YExpression.Convert(YExpression.Box(ynParamI0), typeof(object)),
            // YExpression.TypeAs(ynParamI0, typeof(object)),
            // YExpression.Convert(ynParamI0, typeof(object)),

            // YExpression.TypeAs(YExpression.Box(yconstant0), typeof(object)),
            // YExpression.Convert(YExpression.Box(yconstant0), typeof(object)),
            // YExpression.Convert(YExpression.Box(yconstant0), typeof(object), true),
            // YExpression.TypeAs(yconstant0, typeof(object)),
            // YExpression.Convert(yconstant0, typeof(object)),
            // YExpression.Convert(yconstant0, typeof(object), true),
            YExpression.Box(yconstant0),

            // new YConstantExpression(0, typeof(object)),

            // else return (int)method(n - 1) + (int)method(n - 2);
            YExpression.TypeAs(
                YExpression.Unbox(YExpression.Invoke(ymethodInvokeIO, ynParamI0 - yconstant1), typeof(int)) +
                    YExpression.Unbox(YExpression.Invoke(ymethodInvokeIO, ynParamI0 - yconstant2), typeof(int)),
                typeof(object)
            )
        ),
        ynParamI0
    );
    var ypackExpr = YExpression.Lambda<Func<Func<int, object>>>(
        "ypackExpr",
        YExpression.Block(
            // Func<int, object> fibC0 = null;
            new[] { ymethodInvokeIO }.AsSequence(),
            YExpression.Assign(ymethodInvokeIO, ymethod),
            ymethodInvokeIO
        )
    );
    return ypackExpr.CompileWithNestedLambdas()();
}

Not working - ArrayTests.cs - array.toString()

Assert.AreEqual("1,two,3", Evaluate("array.toString()"));

Evaluate("var array = [1, ,3]");
Evaluate("Array.prototype[1] = 'two'");
Evaluate("Array.prototype[20] = 'twenty'");

output should be 1,two,3 but it gives only 1,,3; as this doesn't take two - as 2

.NET MAUI Crash when using version > 1.2.59

Hi

I have been working with YantraJS in an experimental .NET MAUI project. I have been using version 1.2.59 and have had things working well on Windows, Android and iOS.

When attempting to update to a version later than 1.2.59, my app crashes on Android and iOS but works as before on Windows.

Only a single line of code in my app was needed to be changed to use a later version which was -

jsContext["__dataContext"] = new ClrProxy(dataContext);
to
jsContext["__dataContext"] = ClrProxy.From(dataContext);

Note that this line of code is not reached before that crash occurs.

In analyzing the problem, I have found that the crash occurs from version 1.2.93 onwards, and still occurs in the latest version as of today - 1.2.106.

On Android the last debug console output shows the following before the crash -

[monodroid-assembly] open_from_bundles: failed to load assembly YantraJS.Core.dll
Loaded assembly: /data/data/com.myapp.net/files/.__override__/YantraJS.Core.dll [External]
[monodroid-assembly] open_from_bundles: failed to load assembly YantraJS.ExpressionCompiler.dll
Loaded assembly: /data/data/com.myapp.net/files/.__override__/YantraJS.ExpressionCompiler.dll [External]
[i.myapp.ne] Closures.set dateTimeFormat-:0,0: not enough values (1 < 2) on stack at 0008
[i.myapp.ne] * Assertion at /__w/1/s/src/mono/mono/mini/interp/transform.c:4488, condition `td->sp >= td->stack' not met
[libc] Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 14573 (i.myapp.net), pid 14573 (i.myapp.net)

On iOS there is less output available but what is reported is similar in nature -

2023-01-20 15:48:49.088647+1100 MobileApp[81252:2402105] warning: Closures.set dateTimeFormat-:0,0: not enough values (1 < 2) on stack at 0008
2023-01-20 15:48:49.088965+1100 MobileApp[81252:2402105] error: * Assertion at /Users/runner/work/1/s/src/mono/mono/mini/interp/transform.c:4488, condition `td->sp >= td->stack' not met

As previously mentioned, there was no change in behavior on Windows and the app is working as before.

In both cases it seems like something to do with setting the dateTimeFormat when the YantraJS module is initializing.

If the YantraJS package reference is reverted back to version 1.2.59 and the single line of code changed back to use new, everything works fine again.

Xamarin Error

Hi I'm not sure if this library supports Xamarin but I tried the sample code

var context = new JSContext();

// create global function
context["add"] = new JSFunction((in Arguments a) => {
    return new JSNumber(
         (a[0]?.IntValue ?? 0) + (a[1]?.IntValue ?? 0)
    );
});

var result = context.Eval("add(4,5)", "script.js");

and got the following error

System.InvalidProgramException: 'Invalid IL code in (wrapper dynamic-method) YantraJS.Closures:body-:0,0 (YantraJS.Closures,YantraJS.Core.Arguments&): IL_00d0: pop       

AOT (Trimming) Exception.

The library doesn't seem to work when producing a self contained, trimmed, executable.
The code of the program is:

using YantraJS.Core;
using var ctx = new JSContext();

Console.WriteLine(ctx.Eval("'Hi'").ToString());

Running without trimming works, and prints Hi. When trimming is on, running said executable produces:

Unhandled exception. System.MissingMethodException: Cannot dynamically create an instance of type 'YantraJS.Core.JSJSON'. Reason: No parameterless constructor defined.
   at System.RuntimeType.ActivatorCache..ctor(RuntimeType)
   at System.RuntimeType.CreateInstanceOfT()
   at System.Activator.CreateInstance[T]()
   at YantraJS.Core.JSContext.<.ctor>g__CreateInternalObject|74_0[T](KeyString)
   at YantraJS.Core.JSContext..ctor(SynchronizationContext )
   at Program.<Main>$(String[]) in D:\Projects\GameEditor\GamePlayer.Desktop\Program.cs:line 2

Improve `true` literal

For example,

			while (JSBoolean.True.BooleanValue)
			{
				JSVariable jSVariable12 = new JSVariable(JSUndefined.Value, "baseKey");
				JSVariable jSVariable13 = new JSVariable(JSUndefined.Value, "bp");

YantraJS.Core.JSException: 'Unexpected token UnsignedRightShift: >>> at 1, 39'

Hi there,

I've found another issue with javascript compilation. The following code, that runs ok in Chrome, won't compile:

(function foo(x) { return 0xffff & +x >>> 16; })(1234567)

Throws this exception:

YantraJS.Core.JSException
  HResult=0x80131500
  Message=Unexpected token UnsignedRightShift: >>> at 1, 39
  Source=YantraJS.Core
  StackTrace:
at Compile in Unknown:line 1

Steps to reproduce:

  1. Run the following C# in net6 (Program.cs):
    using YantraJS;
    using YantraJS.Core;
    
    new JSContext();
    CoreScript.Evaluate("(function foo(x) { return 0xffff & +x >>> 16; })(1234567)");

.Net 6 "Object reference not set to an instance of an object" on import statement

I am trying to make some extensions and testing

When i try evaluate this code

import clr from "clr";

var Random = clr.getClass("System.Random");
var r = new Random(); // this will create instance of `System.Random`.
var n = r.next();

console.log(n)

i get exception
Object reference not set to an instance of an object


  at YantraJS.Core.FastParser.Compiler.FastCompiler.VisitImportStatement(AstImportStatement importStatement) in D:\projects\yantra\YantraJS.Core\FastParser\Compiler\FastCompiler.VisitImportStatement.cs:line 29
     at YantraJS.Utils.AstMapVisitor`1.Visit(AstNode node) in D:\projects\yantra\YantraJS.Core\FastParser\Ast\AstMapVisitor.cs:line 117
     at YantraJS.Core.FastParser.Compiler.FastCompiler.VisitProgram(AstProgram program) in D:\projects\yantra\YantraJS.Core\FastParser\Compiler\FastCompiler.VisitProgram.cs:line 58
     at YantraJS.Utils.AstMapVisitor`1.Visit(AstNode node) in D:\projects\yantra\YantraJS.Core\FastParser\Ast\AstMapVisitor.cs:line 45
     at YantraJS.Core.FastParser.Compiler.FastCompiler..ctor(StringSpan& code, String location, IList`1 argsList, ICodeCache codeCache) in D:\projects\yantra\YantraJS.Core\FastParser\Compiler\FastCompiler.cs:line 118
     at YantraJS.CoreScript.<>c__DisplayClass0_1.<Compile>b__0() in D:\projects\yantra\YantraJS.Core\CoreScript.cs:line 43
     at YantraJS.Emit.DictionaryCodeCache.<>c__DisplayClass2_0.<GetOrCreate>b__0(StringSpan k) in D:\projects\yantra\YantraJS.Core\Emit\DictionaryCodeCache.cs:line 21
     at YantraJS.Core.Core.Storage.ConcurrentStringMap`1.GetOrCreate(StringSpan& key, Func`2 value) in D:\projects\yantra\YantraJS.Core\Core\Storage\ConcurrentStringMap`1.cs:line 93
     at YantraJS.Emit.DictionaryCodeCache.GetOrCreate(JSCode& code) in D:\projects\yantra\YantraJS.Core\Emit\DictionaryCodeCache.cs:line 20
     at YantraJS.Emit.DictionaryCodeCache.YantraJS.Emit.ICodeCache.GetOrCreate(JSCode& code)
     at YantraJS.CoreScript.Compile(StringSpan& code, String location, IList`1 args, ICodeCache codeCache) in D:\projects\yantra\YantraJS.Core\CoreScript.cs:line 46
     at YantraJS.CoreScript.Evaluate(String code, String location, ICodeCache codeCache) in D:\projects\yantra\YantraJS.Core\CoreScript.cs:line 70
     at YantraJS.Core.JSContext.<>c__DisplayClass96_0.<<Eval>b__0>d.MoveNext() in D:\projects\yantra\YantraJS.Core\Core\JSContext.cs:line 693
  --- End of stack trace from previous location ---
     at Microsoft.Threading.AsyncPump.Run[T](Func`1 func) in D:\projects\yantra\YantraJS.Core\Core\Promise\AsyncPump.cs:line 32
     at YantraJS.Core.JSContext.Eval(String code, String codeFilePath) in D:\projects\yantra\YantraJS.Core\Core\JSContext.cs:line 692
     at Program.<Main>$(String[] args) in D:\projects\yantra\test\Program.cs:line 10

During debugging, it was found that the variable "require" is null
and when calling require.Expression a NullReferenceException occurs
Please Fix
изображение

Additional Info

Code for test
изображение

My patch, that i want PR (this doent break code ExpressionCompiler)

изображение

Question about eval and CSP

Hello,

I've got a tiny question (or feature request). Is there a way to enforce CSP when executing script using Yantra?

E.g. consider the following code:

CoreScript.Evaluate("new Function(\"return this\")()");

returns undefined.

I am wondering if there is a way to configure yantra to throw an exception when doing dynamic JavaScript evaluation, e.g. eval(str), new Function(str)() or string arguments for setTimeout and setInterval functions?

Many thanks.

Ability to disable a Camel case at the engine level

Hello, Akash!

Most JS engines, when embedding .NET types and objects, uses a Pascal case to access its members. I know that this behavior can be changed using an JSExportSameName attribute, but this is not always convenient. It would be convenient to disable a Camel case when creating an instance of the JSContext class.

Optimize `(...arguments)`

Optimize (...arguments), we can pass reference to existing Arguments struct as we no longer use callee.

No override Symbol.iterator for array.

This was purposely done, but we might revisit this.

//Assert.AreEqual("6,2,9", Evaluate(@"
// var x = [9, 2, 6];
// x[Symbol.iterator] = function() {
// var i = 3;
// return {
// next: function() {
// i --;
// return i < 0 ? { done: true } : { value: x[i] };
// }
// };
// };
// Int16Array.from(x).toString()"));

Not Working - public void toString() - NumberTests.cs - Octal base

    //  Assert.AreEqual("-115.4621320712601014", Evaluate("(-77.598).toString(8)"));
        // Assert.AreEqual("0.00142233513615237575", Evaluate("0.003.toString(8)"));
      //  Assert.AreEqual("27524716460150203300000000000000000", Evaluate("15e30.toString(8)"));
      //  Assert.AreEqual("0.252525252525252525", Evaluate("(1/3).toString(8)"));

Also, below tcs expected result were modified:
// Assert.AreEqual("18014398509481990", Evaluate("18014398509481992 .toString()"));
// Assert.AreEqual("18014398509482010", Evaluate("18014398509482008 .toString()"));
// Assert.AreEqual("1234567890123456800", Evaluate("1234567890123456789 .toString()"));
// Assert.AreEqual("2234567890123456800", Evaluate("2234567890123456789 .toString()"));
// Assert.AreEqual("3234567890123457000", Evaluate("3234567890123456789 .toString()"));
// Assert.AreEqual("4234567890123457000", Evaluate("4234567890123456789 .toString()"));
// Assert.AreEqual("72057594037927940", Evaluate("72057594037927944 .toString()"));
// Assert.AreEqual("72057594037927950", Evaluate("72057594037927945 .toString()"));
to c# specific result

YantraJS.Core.JSException: 'Unexpected token EOF: at 0, 0'

Hi,

Great work with this library. I have been evaluating it for some of my projects. Unfortunately, I am having an issue with some JS code.

Attempting to compile the following javascript code:

(function(){return 1; /***/ })()

Throws this exception:

YantraJS.Core.JSException
  HResult=0x80131500
  Message=Unexpected token EOF:  at 0, 0
  Source=YantraJS.Core
  StackTrace:
at Compile in Unknown:line 0

Steps to reproduce:

  1. Run the following C# in net6 (Program.cs):
    using YantraJS;
    using YantraJS.Core;
    
    new JSContext();
    CoreScript.Evaluate("(function(){return 1; /***/ })()");

Workaround:

Obviously, I can remove the comments 😺 (e.g. using regex), but this is just one example of a code coming from Webpack that I need to execute dynamically so more permanent solution would be appreciated.

ExpressionTest.cs - eval and arguments in strict-mode yet not supported

// Strict mode: left-hand side cannot be 'eval' or 'arguments'.
        //Assert.AreEqual("SyntaxError", EvaluateExceptionType("'use strict'; eval = 5;"));
        //Assert.AreEqual("SyntaxError", EvaluateExceptionType("'use strict'; arguments = 5;"));
        //Assert.AreEqual("SyntaxError", EvaluateExceptionType("'use strict'; function f() { eval = 5; } f()"));
        //Assert.AreEqual("SyntaxError", EvaluateExceptionType("'use strict'; function f() { arguments = 5; } f()"));
        //Assert.AreEqual("SyntaxError", EvaluateExceptionType("function f() { 'use strict'; eval = 5; } f()"));
        //Assert.AreEqual("SyntaxError", EvaluateExceptionType("function f() { 'use strict'; arguments = 5; } f()"));

        // Strict mode: left-hand side cannot be 'eval' or 'arguments' (compound assignment).
        //Assert.AreEqual("SyntaxError", EvaluateExceptionType("'use strict'; eval += 5;"));
        //Assert.AreEqual("SyntaxError", EvaluateExceptionType("'use strict'; arguments += 5;"));
        //Assert.AreEqual("SyntaxError", EvaluateExceptionType("'use strict'; function f() { eval += 5; } f()"));
        //Assert.AreEqual("SyntaxError", EvaluateExceptionType("'use strict'; function f() { arguments += 5; } f()"));
        //Assert.AreEqual("SyntaxError", EvaluateExceptionType("function f() { 'use strict'; eval += 5; } f()"));
        //Assert.AreEqual("SyntaxError", EvaluateExceptionType("function f() { 'use strict'; arguments += 5; } f()"));

unShift - JSArrayPrototype

// Check boundary conditions.
Assert.AreEqual(4294967295.0, Evaluate("new Array(4294967293).unshift(1, 2)"));

Issue is in JSOBject.cs file
internal override void MoveElements(int start, int to)

Improve Stackguard

Try improving stack guard by measuring pointer distance instead of counter.

ExpressionsTests.cs - 'this' TC - delete - strict mode doesn't work

this is not available

// Deleting a global variable fails.
Assert.AreEqual(false, Evaluate("Object.getOwnPropertyDescriptor(this, 'delete_test_1').configurable"));

This doesnt work in strict mdoe

// Delete from a parent scope.
//Assert.AreEqual(false, Evaluate("a = 5; function f() { delete a } f(); this.hasOwnProperty('a')"));

Not Implemented - if the array is in the prototype - nested - ArrayTests.cs

Evaluate("var array = Object.create(['one', 'two', 'three'])");

Assert.AreEqual(3, Evaluate("array.length")); - should return 3, but gives Object reference not set to an instance of an object.

Assert.AreEqual("one", Evaluate("array[0]"));
Assert.AreEqual("one", Evaluate("array['0']"));
Assert.AreEqual("two", Evaluate("array[1]"));
Assert.AreEqual("three", Evaluate("array[2]"));

ClrProxy documentation

The documentation on ClrProxy was outdated but I was able to figure out how use it. The following is an example.

using YantraJS.Core;
using YantraJS.Core.Clr;

var synchronizationContext = new SynchronizationContext();
var context = new JSContext(synchronizationContext);

var calculator = new Calculator();
context["calculator"] = ClrProxy.From(calculator);

var a0 = await context.ExecuteAsync("calculator.add(1,1)");                 // a0 = {2} JSNumber
var a1 = await context.ExecuteAsync("await calculator.addAsync(1,1);");     // a1 = {2} JSNumber

public class Calculator
{
    public int Add(int x, int y)
    {
        return x + y;
    }

    public Task<int> AddAsync(int x, int y)
    {
        return Task.FromResult(x + y);
    }
}

ExpressionTests.cs - Not supported yet

// Strict mode: attempts to set a variable that has not been declared is disallowed.
// Assert.AreEqual("ReferenceError", EvaluateExceptionType("'use strict'; asddfsgwqewert = 'test'"));
// Assert.AreEqual("ReferenceError", EvaluateExceptionType("function foo() { 'use strict'; asddfsgwqewert = 'test'; } foo()"));

ExpressionTests.cs FunctionCall: Not supported TCs

// In compatibility mode, undefined and null are converted to objects.
//CompatibilityMode = CompatibilityMode.ECMAScript3;
//try
//{
// Assert.AreEqual(true, Evaluate("hasOwnProperty('NaN')"));
// Assert.AreEqual(true, Evaluate("hasOwnProperty.call(null, 'NaN')"));
// Assert.AreEqual(true, Evaluate("hasOwnProperty.call(undefined, 'NaN')"));
//}
//finally
//{
// CompatibilityMode = CompatibilityMode.Latest;
//}

await keyword

The following code is resulting with the error: System.ArgumentOutOfRangeException: StartIndex cannot be less than zero. (Parameter 'startIndex')

var synchronizationContext = new SynchronizationContext();
var context = new JSContext(synchronizationContext);
await context.ExecuteAsync("const sleep = ms => new Promise(r => setTimeout(r, ms));");
await context.ExecuteAsync("await sleep(1000);");

Am I doing something wrong?

Sandboxing

I've summarily checked the codebase and it seems there aren't many options to sandbox the scripts. Is this in the scope of this project?
If so, it would be great to be able to do the following (in descending priority):

  • limit CLR interop on a whitelist basis
  • limit the number of instructions to be executed
  • limit total memory allocated
  • limit the recursion depth
  • limit the total execution time

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.