Why does JavaScript get compiled to machine code?
Asked Answered
K

2

5

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

Korry answered 7/6, 2020 at 0:36 Comment(2)
The javascript in an electron app isn't completely compiled to native code, as the executable that gets built is actually a chromium based web appZiguard
Maybe helpful: softwareengineering.stackexchange.com/questions/291230/…Cubic
C
6

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.

Cubic answered 7/6, 2020 at 0:44 Comment(0)
Z
0

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

Ziguard answered 7/6, 2020 at 0:50 Comment(1)
Note that the big complication with Javascript is that the JIT-compiler has to find out if x can be a native integer type (and then put into a CPU register directly and be used with addi) or if it needs more work. Javascript does not have declared types, you could do x = x*2.87 or even x = "Hello" in the next line. With something like JVM bytecode or WASM, there is exact typing at least.Cubic

© 2022 - 2024 — McMap. All rights reserved.