Skip to content
Akash Kava edited this page Sep 19, 2022 · 13 revisions

Managed JavaScript Runtime

YantraJS is a JavaScript runtime written in .NET Standard. Yantra has two components, Expression Compiler and JavaScript engine.

.NET Standard 2.0

Since this is written in .NET Standard 2.0, it runs everywhere except iOS which enforces JIT restrictions. However, there may be a way to interpret IL with mono interpreter but we haven't explored it yet.

Comparison with V8

Running V8 in CLR is expensive, as both V8 and CLR contain same set of features such as garbage collection, threading, and moving objects from to and from V8 hurts performance. And native compilation requirement of V8 puts lot of pressure on maintaining and troubleshooting. So we wanted to create a JavaScript engine which will do everything inside CLR and will try to match performance of other engines. Matching V8 performance is out of scope as C# itself is an higher level language and IL will be JIT compiled at runtime. But we look at Yantra is simple way to integrate with other larger .NET projects. Simplicity in integration overcomes performance drawbacks. Currently Yantra is twice slower compared to V8. However, as time goes, we will certainly try to improve the speed. This is also the primary reason we are trying write lengthy code and avoid runtime inlining as currently there is no macro support in C#.

YantraJS.ExpressionCompiler

Expression compiler is similar to .NET's Linq Expression LambdaCompiler and supports compiling expression to method builder. It is not drop in replacement but the API is quite familiar to Linq Expressions.

YantraJS.Core

YantraJS.Core is a JavaScript engine, which contains Scanner, Parser and Compiler which compiles JavaScript AST to ExpressionCompiler Expressions. That in turn are converted to IL and it can be saved.

ECMAScript Conformance

Currently we are seeing more than 70% conformance to ECMAScript, reaching 100% is little out of scope as it is very huge and Yantra is only one year old. We are focusing on supporting most used JavaScript patterns instead of targeting 100% compliance due to limited development bandwidth.

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.

* 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, it does not take .js extension into account. We are trying to make a workaround and we will update the product soon. 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, this may lead to some deadlocks.

Mixed Modules Roadmap

  1. Detect the loading order, first check if the same named file exists, if yes, load it, allow auto appending extension in the configuration, so module loader can load corresponding files accordingly.
  2. Create correct algorithm to resolve module name to support loading of CSX module in the mix. YantraJS supports loading module independent of the implementation. We can support other languages like python, php in the YantraJS. This is only possible to load modules without extension.

Unsupported

Following cases are not supported due to differences in V8 and DotNet.

  1. Date.prototype.setFullYear(0) not supported as .NET DateTime does not support setting year to 0. It will set to an Invalid Date.
  2. Currently, Intl.DateTimeFormat of ECMA script is not supported. However, you can use .Net String Formats.
  3. Minimum Date in .NET is 01/01/0001 and maximum date is 31/12/9999. However, other JavaScript engines support dates beyond this date range. We are using .NET's inbuilt DateTime for JavaScript's Date, hence we cannot provide true EcmaScript Date range.
  4. Double precision is different in double compared to V8, so edge cases of number arithmetic provides slightly different results compared to V8.