Are Runtime environments and Compilers/Interpreters the same? - javascript

I'm just getting started with Node.js and I have quite a bit of background in Python and C++. I got to know that Node.js is a runtime environment but I'm having a rough time understanding what actually it does to a code that makes it different from a compiler. It would be better if someone can explain how specifically runtime environments differ from typical compilers and interpreters.

Let's take it this way:
Node.js is a JavaScript runtime built on Chrome’s V8 JavaScript engine.
V8 is the Google Javascript engine, the same engine is used by Google Chrome.
There are other JS engines like SpiderMonkey used by Firefox, JavaScriptCore used by Safari, and Edge was originally based on Chakra but it has been rebuilt to use the V8 engine.
We must understand the relationship first before moving to how the V8 works.
JavaScript engine is independent of the browser in which it's hosted. This key feature enabled the rise of Node.js. V8 was chosen to be the engine that powered Node.js.
Since V8 is independent and open-source, we can embed it into our C++ programs, and Nodejs itself is just a program written in C++. Nodejs took the V8 and enhanced it by adding features that a server needs.
JavaScript is generally considered an interpreted language, but modern JavaScript engines no longer just interpret JavaScript, they compile it.
Since you have a C++ background, C++ performs what is called ahead-of-time (AOT) compilation, the code is transformed during compilation into machine code before the execution.
JavaScript on the other side is internally compiled by V8 with just-in-time (JIT) compilation is done during execution. While the code is being executed by the interpreter it will keep track of functions that are called very often and mark them as hot functions then it will compile them to machine code and store them.

A compiler is a program that converts code from one language to another. In Java for example we have a the java compiler javac that you can run on your .java files to compile your code into platform independent java file (can be understood and executed by any jvm).
Since you are new to JavaScript, you will encounter the transpilers (like babel) that turns your next generation JavaScript code into a legacy JavaScript code that can be handled by all browsers (even old ones).
A runtime is a more vague concept. It can go from being a set of functions to run a compiled code on a specefic operating system to being the whole environment in which your program runs.
For the case NodeJS, it's the environment on which you can run a JavaScript program out of the browser. It took the V8 Engine of Chrome that runs JavaScript on the Chrome browser and made it available everywhere. That's how JavaScript moved from being a Client side Programming Language that runs only on the browser to a server side Programming Language that can run on servers equiped with the runtime environment NodeJS.

A few simple points that might help:
C/C++ code will be compiled by the C/C++ compiler into the machine code and will not need any runtime environment to run (mostly, except the run-time libraries)
Python code needs Python interpreter to execute it. As you say you have background in C++/Pythons you must be familiar with all these nitty-gritty
JavaScript was meant to run in the browser and it does mostly, however some smart folks thought of running it outside the browsers and they created the JavaScript execution engine (which is kind of stand alone JavaScript executor) and Node.js is just one of them. It simply runs the JavaScript code outside browser on it's own. The execution is still interpretation of JavaScript code so it is just an interpreter with hell lot of support functions for managing the runtime dependencies, package management, etc.

Related

What exactly does "Javascript can be run outside the browser" mean in plain English? [duplicate]

This question already has answers here:
What is client side javascript and what is server side javascript?
(8 answers)
Closed 9 months ago.
I'm learning Javascript, and I keep seeing this phrase being used when speakers are explaining NodeJS and the V8 engine in relation to Javascript. I know because of Node, we can run JS "outside of the browser," but what does that mean? Oftentimes, instructors use terms I don't know yet (like "server-side scripting") to explain, which makes it difficult to understand.
From what I know so far, it means that you can use JS like a back-end language..? Whereas "running inside a browser," means you can only code visual/front-end interactions, things only users see. Am I correct?
Yes you are more or less on the right track. The V8 engine is what powers both chrome and nodejs. When used with nodejs, it provides a runtime environment for javascript that allows JS code to be run "outside the browser". Traditionally the only place javascript could run was in a browser that implemented support for ECMAScript (all major browsers). But then along came node.js, which pulled out the critical v8 engine from chrome, and mixed with LibUV for C++ support, created the first runtime that successfully allowed Javascript to run without a browser to run the code. With Node.js (and Deno if you are curious) we can implement a variety of "back-end", server-side, code. Think anything you could program in another language now available to be programmed in Javascript. Node.js and Express js are absolutely great for running web servers, microservices, and many other services independent from a browser run time environment.
Originally, the ability to process the JavaScript language was something that Netscape added to their browser so that it could process not only HTML and CSS, but also JavaScript. Microsoft followed suit and so did all the other browsers. That's what we call running JavaScript within the browser.
But (as an example) Node.js is a command line runtime that includes the core JavaScript runtime, but extracted from the Chrome browser itself. So, with Node, you have the ability to write and run JavaScript, but you aren't running it inside of a browser and therefore you don't have the Document Object Model (DOM) or the Browser Object Model (BOM) available to you because those are APIs that are native to browsers.
But you do have the core JavaScript language and can create applications that do all sorts of non-browser tasks.
You'll find that many other development environments and tools have similar set ups, where the core JavaScript runtime has been added so that you can develop with JavaScript, but outside of a browser.

When does the V8 engine compile JS code into machine code within a web browser? [duplicate]

I was studying the inner workings of V8 and came across the term JIT compiler. Initially, I read in this article https://www.quora.com/How-does-the-JIT-compiler-work-in-JS that JIT compiler in V8 is called "Ignition" which is interpreter. Then, I came to conclusion that JIT compiler is just interpreter. But later I found another article https://blog.logrocket.com/how-javascript-works-optimizing-the-v8-compiler-for-efficiency/ describing jit-compilation as the combination of both interpreter and compiler. Guys, is JIT compiler a really a combination of interpreter and compiler? or Is JIT compiler is just interpreter only?
V8 developer here. Just to clarify and expand what commenters have been pointing out already:
"JIT" means "just in time", and means that some execution environment dynamically (i.e. at runtime) decides to produce something (typically machine code -- colloquially, "JIT" tends to mean "just-in-time compilation", although if you decide to prepare a meal exactly when you're hungry and then eat it right away when it's done, then that's technically also "JIT" preparation.) The canonical opposite would be a language like C/C++, which is compiled by the developer, long before being delivered to and executed by the user. Another "opposite" in a different direction is an execution environment that executes something without producing machine code dynamically. Such environments are typically called "interpreters".
In the past, V8 used to always produce machine code. It simply had no way to execute JavaScript that did not involve compiling it to machine code first. Obviously this happened on the client, so it was a textbook example of a just-in-time compiler (or, more accurately, a set of several compilers... oh well, details!).
In recent years, V8 has had an interpreter as its first execution tier. Now usage of terms gets complicated, because this interpreter "compiles" JavaScript "just in time" to bytecode (which is then interpreted), but when someone says "JIT compiler", they usually mean that it's not an interpreter.
V8 also has an optimizing compiler that produces machine code. It runs at runtime (when a function is considered hot), so it's a just-in-time compiler.
Transpile is to compost and "pile on to an ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT target."
target triple = "x86_64-apple-macosx10.7.0"
-march=x -mcpu=y, and -mattr=a,-b,+c.
ExecutionEnvironment/TargetSelect/selectTarget()
Can ...[one compile and execute with a triple target]?
For this reason, I would call v8 an interpreter/compiler, yet not sufficiently an interpreter yet for allegedly & sufficiently targeting the cloudflare service worker with rust-llvm wraps, alone - after all & to boot an interpreter is for application programming or graphical user interfaces (not a service worker for a v8 'edge' server). I believe the abstract syntax tree, target, and scope that global receiver mirrors all to be diametrically synonymous thus far in[ my] research.

Is web browser JavaScript runtime?

In Node.js website, they say Node.js is a JavaScript runtime.
Are web browsers like Chrome, Firefox, Edge, ... JavaScript runtimes?
I thought of course, web browser is JS runtime. But I'm confused, In this video 12:10~ He says Web browser is not just JavaScript runtime because it can do more things
at one time, it can give us other things.
But I think V8 engine only can do one thing at one time, while JS runtime can do more things than one at one time.
Am I wrong?
A browser contains a Javascript engine (for example Chrome v8). The engine implements a Javascript runtime, which includes the call stack, heap and event loop. The browser also usually includes a set of APIs that augment the Javascript runtime and make asynchronous code execution possible.
NodeJS also implements a Javascript runtime using Chrome's v8 engine as well as the Libuv library (event loop and worker threads).
Here's a good video that breaks this all down:
https://www.youtube.com/watch?v=4xsvn6VUTwQ
They are right, a JavaScript runtime just executes the JavaScript code.
All Web browsers include a JavaScript runtime engine(RE) that executes js code for them but they also have other plugins like java or flash, as well as an html/dom parser and renderers that are not part of the RE, even if those modules were written in JavaScript it does not mean they would be part of the RE.

How is Javascript translated to bytecode?

I can't find information on the web how W3C languages compile to machine code. I know that the gap between the web and the processor must be somehow the browser, but how does it work and what are the steps till Javascript is executed in the processor?
Links to scientific documents would be also greatly appreciated.
It's up to the implementation; the specification is the full description of the language and how it's supposed to work, implementations are free to satisfy that implementation in any way they like. Some implementations seem (from the outside) to run it purely as an interpreter in the old sense; others may or may not compile to bytecode; V8 (the JavaScript engine in Chrome, Chromium, Brave, Node.js, and others) used to compile to machine code (twice, for hotspots in the app), but now starts out parsing to bytecode and running it in an interpreter and only compiling hotspots as necessary (details). (There's also a V8 mode where it only interprets, which they're experimenting with for environments where compiling at runtime isn't an option, such as iOS where non-Apple apps aren't allowed to allocate executable memory.)
The V8 team (V8 being the JavaScript engine in Chromium and Chrome) periodically publish descriptions of how they get the fantastic speed out of V8 that they do. You may find some of that on the V8 blog.
Naturally, you can also kick around the code of any of the open-source implementations. V8 and SpiderMonkey (Mozilla's engine) are the two major open-source ones I know.
This may help : http://www.ecma-international.org/publications/standards/Ecma-262.htm
There is no spec for how to translate into bytecode (That is up to the browser developers) but there are specs about how the language should behave
For Firefox there's some specifications on its bytecodes:
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Bytecodes
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/Bytecode
For V8 it's compiled to native code directly:
http://jayconrod.com/posts/51/a-tour-of-v8-full-compiler
Javascript (as it's name suggests) is a dynamic scripting language. Meaning that it's code is analysed and executed at runtime by the web-browser's Javascript engine.
It is up to the Web-browser, how it wants to deal with Javascript. Some may generate an intermediate language, or bytecode. Some may directly analyse and execute it.
Here are the steps to the simplest way to execute Javascript (parsing and executing at runtime):
Parsing and Preprocessing (recursive descent or otherwise)
Analysis
Execution
Chrome's Javascript Engine compiles Javascript to native platform-specific machine code (for optimum performance) It also has a Garbage Collection Mechanism.
In addition to the useful, specific answers already given, the phrase 'adaptive optimisation' is probably worth looking up if performance is your main interest. JavaScript and its interpreters are just the latest instance of systems that need to convert something else to machine code at runtime, so there's plenty of wider reading. The bytecode forms of Pascal, Smalltalk, Java, etc can easily enough be viewed as an intermediate form in the process of running a defined language on arbitrary hardware — Apple's SquirrelFish explicitly creates a bytecode and uses a JIT compiler on that, for example.

Javascript Engines Advantages

I am confused about JavaScript engines right now. I know that V8 was a big deal because it compiled JavaScript to native code.
Then I started reading about Mozilla SpiderMonkey, which from what I understand is written in C and can compile JavaScript. So how is this different from V8 and if this is true, why does Firefox not do this?
Finally, does Rhino literally compile the JavaScript to Java byte code so you would get all the speed advantages of Java? If not, why do people not run V8 when writing scripts on their desktops?
There are various approaches to JavaScript execution, even when doing JIT. V8 and Nitro (formerly known as SquirrelFish Extreme) choose to do a whole-method JIT, meaning that they compile all JavaScript code down to native instructions when they encounter script, and then simply execute that as if it was compiled C code. SpiderMonkey uses a "tracing" JIT instead, which first compiles the script to bytecode and interprets it, but monitors the execution, looking for "hot spots" such as loops. When it detects one, it then compiles just that hot path to machine code and executes that in the future.
Both approaches have upsides and downsides. Whole-method JIT ensures that all JavaScript that is executed will be compiled and run as machine code and not interpreted, which in general should be faster. However, depending on the implementation it may mean that the engine spends time compiling code that will never be executed, or may only be executed once, and is not performance critical. In addition, this compiled code must be stored in memory, so this can lead to higher memory usage.
The tracing JIT as implemented in SpiderMonkey can produce extremely specialized code compared to a whole-method JIT, since it has already executed the code and can speculate on the types of variables (such as treating the index variable in a for loop as a native integer), where a whole-method JIT would have to treat the variable as an object because JavaScript is untyped and the type could change (SpiderMonkey will simply "fall off" trace if the assumption fails, and return to interpreting bytecode). However, SpiderMonkey's tracing JIT currently does not work efficiently on code with many branches, as the traces are optimized for single paths of execution. In addition, there's some overhead involved in monitoring execution before deciding to compile a trace, and then switching execution to that trace. Also, if the tracer makes an assumption that is later violated (such as a variable changing type), the cost of falling off trace and switching back to interpreting is likely to be higher than with a whole-method JIT.
V8 is the fastest, because it compiles all JS to machine code.
SpiderMonkey (what FF uses) is fast too, but compiles to an intermediate byte-code, not machine code. That's the major difference with V8. EDIT- Newer Firefox releases come with a newer variant of SpideMonkey; TraceMonkey. TraceMonkey does JIT compilation of critical parts, and maybe other smart optimizations.
Rhino compiles Javascript into Java classes, thus allowing you to basically write "Java" applications in Javascript. Rhino is also used as a way to interpret JS in the backend and manipulate it, and have complete code understanding, such as reflection. This is used for example by the YUI Compressor.
The reason why Rhino is used instead of V8 all over the place is probably because V8 is relatively new, so a lot of projects have already been using Rhino/Spidermonkey as their JS engine, for example Yahoo widgets. (I assume that's what you're referring to with "scripts on their desktops")
edit-
This link might also give some insight of why SpiderMonkey is so widely adopted.
Which Javascript engine would you embed in your application?
If you want to see how the various in-browser Javascript engines stack up, install Safari 4 (yes it runs on Windows now too!), Chrome V8, Firefox 3.5, and IE 8 (if you are on windows) and run the benchmark:
http://www2.webkit.org/perf/sunspider-0.9/sunspider.html
I believe as Pointy said above, the new Firefox 3.5 uses TraceMonkey that also compiles to intermedit code on the fly using some form of JIT. So it should compare to V8 somewhat favorably. At least it won't be 10x slower than V8 like Firefox 3 SpiderMonkey (without JIT) was.
For me... safari 4.0.3 was 2.5x faster than Tracemonky in Firefox 3.5.3 on Win XP. IE8 was much much slower. I don't have Chrome installed at the moment.
Don't know about Rhino compiling to java bytecode. If it's still interpreting the dynamic features of Javascript such as being able to add attributes to object instances at runtime (example obj.someNewAttribute="someValue" which is allowed in Javascript)... I'm not so sure that it's entirely "compiled" to bytecode, and you might not get any better performance other than you don't have to compile from Javascript source code text every time your Javascript runs. Remember that Javascript allows very dynamic syntax such as eval("x=10;y=20;z=x*y"); which means you can build up strings of code that get compiled at runtime. That's why I'd think Rhino would be mixed-mode interpreted/compiled even if you did compile to JVM bytecode.
The JVM is still an interpreter, albeit a very good one with JIT support. So I like to think of Rhino-on-JVM as 2 interpreter layers (interpreter-on-interpreter) or interpreter^2. Whereas most of your other Javascript engines are written in C, and as such should perform more like interpreter^1. Each interpreter layer can add 5-10x performance degradation as compared to C or C++ (ref Perl or Python or Ruby for example), but with JIT the performance hit can be much lower on the order of 2-4x. And the JVM has one of the most robust & mature JIT engines ever.
So your mileage will definitely vary and you probably would benefit from doing some serious benchmarks if you want a real answer for your intended application on your own hardware & OS.
Rhino can't be too awfully slow, since I know lots of folks are using it. I think it's main appeal is not its speed, but the fact that is easy-to-code/light-weight/embeddable/interpreter that has hooks into Java libraries, which makes it perfect for scripting/configuration/extensibility of your software project. Some text editors like UltraEdit are even embedding Javascript as an alternative macro scripting engine. Every programmer seems to be able to stumble through javascript pretty easily, so it's easy to pick up as well.
One advantage to Rhino is that it runs pretty much anywhere the JVM runs. In my experience, trying to get stand-alone TraceMonkey or SpiderMonkey to build & run from command line can be a bit painful on systems like Windows. And embedding in your own application can be even more time consuming. But the payback to having an embeddable language would be worth it for a big project, as compared to having to "roll your own" mini scripting solution if that's what you're looking to do.
Scripting with Rhino is really easy if you have Java and the rhino jar, you just write your javascript and run it from command line. I use it all the time for simple tasks.
To respond the question, why native code Vs Byte code...
The native code is faster and for google a strategic choice because they have plan to JS one of them at least is ChromeOS.
A good video about this question is posted on Channel9 with an interview with Lars Bak the man behind V8 can be found here
2022 Update
V8 as also SpiderMonkey do support MultiPass Compilation as also SinglePass Compilation.
Java Rhino got deprecated and replaced by a new concept called Truffle Framework it is part of the GraalVM Stack which is in fact a JVMCI added to the JVM where CI means Compiler Interface. That allows the Truffle Language Implementer Framework to Implement any Language and translate that to Java Byte Code in MultiPass and Single Pass. the ECMAScript implementation is called GraalJS and it comes in 2 Flavors
GraalJS the 1:1 Rhino Replacement including compatability mode for incremental adoption and graal-node a NodeJS Fork where v8 is replaced with the GraalJS Engine.
as sayed Truffle is a Polyglot Language Implementer Framework so that works with any GraalVM Supported Language.
hope that helps and makes some sense since the jar versions do most best work when the whole stack has aligned versions you should alaways install the complet stack:
https://github.com/graalvm/graalvm-ce-builds/releases
download and install that then use the so called gu command to add graaljs
follow the instructions here: https://github.com/oracle/graaljs
Yes GraalVM can in general Compile Single Binary Executeable Files of all Polyglot Languages this is called AOT Compilation it has faster boot times but less throughput it can also do JIT and it can do a mix of both.

Categories

Resources