As far as I understood, JavaScript cannot be compiled ahead of time because of it's dynamic nature. So Interpretation and just in time compilation happens at run time, that affects JavaScript performance. So WebAssembly comes into picture. Languages can be compiled ahead of time into intermediate format (WASM). This gives good performance since there is less runtime overhead.
My question is why JVM cannot be used in place of WebAssembly VM. Java compiled into intermediate format (bytecode). This byte code can be given to browser and JVM can execute it. JVM also supports JIT which helps to achieve near native performance.
So what is the need for new WebAssembly. Why can't JVM be integrated into browser and achieve high performance by leveraging the existing most popular Java language.
There are a great many reasons why the JVM was not deemed a suitable runtime in place of WebAssembly ...
WebAssembly was designed with delivery-over-HTTP and browser-based in mind. For that reason, it supports streaming compilation - i.e. you can start compiling the code while downloading.
WebAssembly was designed to have rapid compilation times (resulting in web pages that load quickly), this is supported by having very simple validation rules compared to Java / JVM languages.
WebAssembly was designed with the concept of a 'host' environment, i.e. the browser.
WebAssembly was designed to be secure and simple, minimising the overall attack surface.
WebAssembly was designed to support a great many languages (C, C++, Rust, ...), whereas the JVM was initially design for a single language, Java.
As a general observation, WebAssembly was designed to support multiple languages on the web. The JVM was designed to support Java on the desktop. It doesn't make either one better than the other in a more general sense.
Finally, the JVM was integrated with the browser (Java Applets), but that didn't work out in the end!
A quote from the High-Level Goals of WebAssembly:
a Minimum Viable Product (MVP) for the standard with roughly the same functionality as asm.js, primarily aimed at C/C++;
So their original goal was running C/C++ program in a web browser, not running Java code.
JVM can run:
JavaScript
Python (Jython)
Ruby (JRuby)
Groovy
Scala
C++ (using JNI)
unfortunately the support for java was removed from the browser, because Sun (former maintainer of java), could not provide adequate support.
Just like the Flash ended up losing.
Related
I recently started some web development, with ASP.NET and some Javascript, and something is confusing me alot.
I always read that JavaScript used to be interpreted until JIT slowly made it so chunks are compiled to machine code (which made browsers alot faster).
This makes no sense to me. How can JavaScript compile to native machine code, if traditional JavaScript apps don't target the machine/CPU to begin with?
I understand if an electron.js app gets compiled to machine code using the NodeJS runtime. That I get. Because it natively compiles to machine code and as far as I understand it, doesn't run in a browser.
If traditional JavaScript apps run in a browser, why must it be compiled to machine code? The browser is responsible for running the code, not the CPU. The CPU runs the browser itself. I actually don't see how the native OS can influence anything that happens in the browser at all or vise versa. Seems like a security issue as well.
Sorry if it's a stupid question, but I can't find any resource that will go beyond saying "Javascript uses JIT"
Thank you!
Lauren
At the end of the day, the CPU has to run the code.
JIT-compiling it down to machine code is one way to make that faster.
How can JavaScript compile to native machine code, if traditional JavaScript apps don't target the machine/CPU to begin with?
It is not "Javascript" that is doing it, it is the browser (or rather, the Javascript execution engine inside the browser), and since it is "JIT" it knowns exactly which CPU to target (this is not done in a generic way, this is done for the specific CPU that the browser is currently running on).
So, yes, there is some mismatch, since Javascript will not use low-level primitive types that the CPU can work with directly, which is why there is a lot of indirection and speculative type inference guess-work. The resulting machine code is much different than you would get from hand-coded assembly, but it can still be a net positive. To help with this, WASM was developed, which is closer to "normal" machine code.
Other intermediate, non-CPU specific formats like JVM bytecode or CLR bytecode or LLVM bitcode are in a similar situation (in that can also be compiled to machine code they do not themselves target directly) -- but they have been "lowered" already from language source code to something close to machine code.
Seems like a security issue as well.
Yes, it can be. The browser has to be careful in what it is doing here, and the OS should sandbox the browser as much as possible.
Executing instructions is easier than running an interpreter, and JIT seeks to take advantage of this for a performance boost. All programs running on your computer become machine code at some point, the only question is which instructions are be executed.
let x=0;
for (let i=0;i<100;++i) {
x+=2;
}
Since it is clear that there are no side effects in a block of code like this, it is faster to compile instructions directly, rather than interpreting each line.
// NIOS 2 assembly, sorry its the only one i know
movi r2,0
movi r3,0
movi r4,100
loop:
addi r2,2
addi r3,1
blt r3,r4,loop
Executing this will be faster than executing the parsing logic for each individual instruction.
TLDR: All programs are always running CPU instructions, so it is faster to minimize the number of instructions by skipping the parsing stage when possible
Instead of having V8 compile JavaScript on the fly and then execute it, isn't it possible to just compile the JavaScript beforehand and then embed the machine code in the page instead of embedding JavaScript in the page?
There are two main problems with shipping machine code on the web:
Portability. No server can afford providing appropriate machine code for all possible system architectures out there (present and future). E.g., V8 already supports 10 different CPU architectures.
Security. No client can afford to run random machine code on their machine without knowing if it can be trusted.
To address (1) you'd generally need to cross-compile machine code, which is more difficult and costly than compiling down from a high-level language. To address (2), you'd need to validate the machine code you receive, which is more difficult and costly than compiling a high-level language.
Machine code also tends to be much larger than high-level code, so there is a bandwidth issue as well.
Now, JavaScript may not be a particularly great choice of high-level language. But it is what we are stuck with as the language of the web.
The way I understand it, the V8 JavaScript engine compiles to machine code anyway so why not just do it beforehand?
According to the W3C HTML5 Scripting specification, there's no standards-based reason why a browser couldn't support machine code with special type attributes (as Chrome does with the Dart language):
The following lists the MIME type strings that user agents must recognize, and the languages to which they refer:
"application/ecmascript"
"application/javascript"
...
User agents may support other MIME types for other languages...
Currently, no browser has implemented such a feature.
I suspect the primary shortcoming of such an approach is that each chip architecture would require a machine-code version of the script compiled for it specifically. This means that in order to support three architectures, a page would need to include a compiled script three times. (And it should be included a fourth time, as plain JavaScript, as a fallback for architectures that you didn't include, or for browsers that can't/don't support compiled code.) This could significantly bloat the size of the page with data that is mostly useless. The increase in load time would seem to significantly offset or completely outweigh whatever time you save on compilation.
An architecture-independent compromise solution like bytecode seems pretty poor: you still need to include the script twice (once for the bytecode, once normally for scripts that don't support it) and you need to do some kind of run-time processing on the bytecode to turn it into machine code.
The multiple-includes-with-fallback problem is exactly why other scripting languages have not made it into the Web environment: they would need coordinated cross-vendor support to be useful. Google is trying with Dart, but it remain to be seen what degree of success they see.
Note that Chrome does cache compiled versions of scripts so a script only needs to be compiled once and then the compiled code is cached for reuse when the user re-visits the page.
So I am asking does each web browser have there own compiler example IE compiles Javascript from a website and generates sequence A of byte code .
On the other hand, google chrome compiles the same Javascript from the same website and generates sequence B .
I am wondering this because if that is the case would it be beneficial to run the compiler on the Javascript and upload the generated byte code to the website rather than the Javascript itself. And send different byte code based on each browser.
Or are there some other limitations.
As others have pointed out, there are different ECMAScript engines and some of them use a JIT (Just-In-Time) compiler while some others use runtime interpreters, being the former the preferred option for most browsers nowadays as it gives some performance benefits over the latter option.
You can see another question about this on: https://softwareengineering.stackexchange.com/questions/138521/is-javascript-interpreted-by-design
For example, V8 is the JavaScript engine used in Google Chrome, node.js and can also be embedded into C++ applications.
About your idea of sending compiled or precompiled code to the client instead of the raw JS, there are some projects working on something similar:
Asm.js consists of a strict subset of JavaScript, into which code written in statically-typed languages with manual memory management (such as C) is translated by a source-to-source compiler such as Emscripten (based on LLVM). Performance is improved by limiting language features to those amenable to ahead-of-time optimization and other performance improvements.
The important fact about Asm.js is that existing JavaScript engines do work quite well with its style of code, so you can start using it right now! But the code it produces is still (a subset of) the JS we know but written in some way that helps JS engines to run it faster:
Of course, there are also a lot of restrictions about what you can do with it, as it is mainly oriented to work with just numbers. See http://ejohn.org/blog/asmjs-javascript-compile-target/
Real support for Asm.js is still a limitation, so you can't use things like "use asm" and although you can run Asm.js code on today browsers and get some performance improvements, it won't be as good as it could be in browsers that could optimize Asm.js code. However, we may start having that and some other improvements in the (hope that near) future. See https://blog.mozilla.org/research/2015/02/23/the-emterpreter-run-code-before-it-can-be-parsed/
Meanwhile, and for a more general purpose JS that needs to work with more than just numbers, you can use Google Closure Compiler. I would recommend that you take a look at the FAQ first, and then you could start playing with it in the online tool.
There are several JavaScript (or rather ECMAScript) implementations in wide use, and while in theory there are standards, most widely used one being ES5 (ECMAScript 5) - yes, not everything in all browsers is properly, consistently implemented (I'm looking at you, old IE).
Here's nice compatibility table for ES5 (the one you're writing in today): http://kangax.github.io/compat-table/es5/
And here's same thing for shiny-new ES6: http://kangax.github.io/compat-table/es6/
Note the disclaimer at the top of these tables:
Please note that some of these tests represent existence, not functionality or full conformance.
Also, on the issue of whether JavaScript is compiled or interpreted language: it is definitely interpreted language - at least originally. But most common JavaScript engines in use today implement JIT (Just-In-Time compiler), translating much of JavaScript to byte or machine code before executing it (ergo - compiling).
Most widely used (and most performant as well) of these engines is V8, used by WebKit (and therefore present in Chrome, Safari, Opera, ... - Node.JS is using it as well). Read more about V8 and its JIT implementation: How the V8 engine works?
Yes, each browser has its own implementation of an ECMAScript engine, most commonly implementing/supporting ECMA-262, commonly known as JavaScript. While there are several large related families of browser engines such as Webkit, each engine further can have its own JavaScript engine. For example, as many have pointed out, Google use the V8 engine. Because these engines each do things a little differently, there is no one set of code that is promised to be deterministic across them, the way say Java code will run the same on any machine that supports the JVM.
Inherently, JavaScript is not compiled like a traditional language such a Java or C/C++. This is why, without the help of a 3rd party program, you cannot find non-syntax errors in your JavaScript code until that code runs. ECMAScript is an interpreted language.
Now, this is the tricky part. Most modern JavaScript engines do in fact compile JavaScript, often to another language (also known as Source-to-Source compiling or transpiling) such as C, to perform performance optimizations on it. Of course, at some point, all code gets compiled into byte code.
Your best bet for writing JavaScript that will work on all major browsers is to use core/standard features. For example, this means passing timestamp string in the form of "yyyy/mm/dd" instead of "yyy-mm-dd" when using new Date() since Firefox does not support the latter format - the Chrome developers simply added it to be nice to you. IE is notorious for handling certain non-standard features differently. I'm a big fan of http://caniuse.com/ to help with this.
Nowadays most javascript engines are JIT compilers. More here: What does a just-in-time (JIT) compiler do?
So yes, javascript is compiled (not interpreted), and most major browsers do it differently.
What are the major differences between the Netscape Enterprise Server implementation of Server-Side JavaScript (SSJS) and the node.js implementation?
Why did not Netscape's implementation gain attention while the node.js seems to be far more popular?
Back in 1999/2000, I used to work at a company that used Netscape Server and SSJS. I don't know how popular it was at the time, but from first hand experience, I can tell you that almost everything about it was terrible:
It was a giant pain to debug (any changes to source files, even static files, required full reloading of the application, which was not a fast operation)
A simple error (such as an uncaught exception) often would lead to catastrophic server failure. Somewhat amusingly, this is the default behavior of NodeJS, although it is much easier to get around this problem with Node.
Although the syntax was JavaScript, it failed to implement one key advantage of modern JavaScript: runtime interpretation. Server Side JS with Netscape Server required compilation before deployment, and therefore dictated a very slow development process.
It followed a multi-threaded execution model (rather than modern JS VMs, which are almost always event-loop based)
Possibly it's biggest weakness was a lack of asynchronous programming support. All IO operations were blocking, and as such it required a heavyweight multithreaded model to support multiple clients. The execution model was more similar to a J2EE container than to modern event driven JavaScript VMs (ie: V8). In my opinion, this is the number one thing that NodeJS gets right: the async philosophy is deeply embedded in the NodeJS development workflow and it is the key to its lightweight, event driven, extremely efficient concurrency model.
Just for giggles, here's a link to the SSJS reference guide from version 1.2 . Starting on page 21, you can see all the standard functions and synchronous APIs for file objects, database queries, etc...
My company ended up switching to ColdFusion shortly thereafter and never looked back.
The main difference would be the evolution of Javascript over the the past 15+ years. Node.js uses the V8 Javascript Engine which would be far more optimized for modern computers.
Wikipedia has a good list of the differences between various server-side JS solutions.
Here is a list of features for Netscape Enterprise Server - provides a good idea of what makes modern SSJS solutions much better.
Why did it not gain attention? Realistically, client-side JS has only recently started to become the standard for web development so it was unlikely anybody would have considered using it for server-side development when it wasn't even really widely adopted for it's original purpose. I say widely adopted in that previously it was always difficult to cater JavaScript solutions to all browsers.
I need some embeddable language for tasks similar to query execution in mongodb. Language should be fast and it should have both JIT and interpreter (for frequent scripts that JIT-compiled and for one-time-run scripts too), should have in-memory runtime that I populate with specific API functions (or classes, whatever) by hand (and nothing "built-in" else like gettime, thread spawning or similar), it should have C API and it should work on ARM (MIPS also would be nice), not too big footprint also would be nice (but this is not critical).
I have two candidates:
Google V8.
Spidermonkey (There was IonMonkey's ARM support announced AFAIK).
I have not experienced embedding languages into C projects before so I have a few questions: recently there was a rumor that V8 is not thread-safe, is this problem still exists? If so, where that lack of thread-safe can cause problems?
Also I would be glad if anyone suggested embeddable language which is more suitable for my requirements (except lua, I can't find any advantages in comparison with js except smaller footprint about what I don't care).
I'm not sure how SpiderMonkey's multithreading embeddability compares to V8's, but I do know that it's possible to do with SpiderMonkey -- we have a few multiprogramming embedders on dev.tech.js-engine that you may want to post followup questions to.
Our web workers implementation in the browser uses one runtime instance per worker (you can multiply instantiate the runtime in a single process) -- we've moved away from an multithread-safe single-runtime approach over the past few years because it's unnecessary for the web and adds a significant amount of complexity to the engine.
An alternative to multiprogramming is also the asynchronous, select-based, run-to-completion approach a la node.
A nit: I don't think an interpreter is really a requirement of yours -- your requirement is fast start up times for one-off code. SpiderMonkey has an interpreter and V8 does not, but V8 has a fast-code-emission (which we tend to call "baseline") JIT compiler that offers comparable performance in that area. That capability is an important requirement for JS on the web in general. :-)