I'm trying to understand the process of how a piece of JavaScript code is executed. So far, I've managed to have most of the layout pictured out, but there's a few gaps that I wish to cover.
I know that a computer's CPU only understands 0's and 1's. So eventually, any code we write (in a high level language) gets transformed into 0's and 1's and is then executed by the CPU. In the case of JavaScript, the main character that makes this journey possible is the JavaScript engine. So that's what I looked into and just picked chrome's V8 to help me picture the whole thing.
So the JavaScript engine first parses the code and eventually generates AST's (Abstract Syntax Tree). Those are then transformed into Bytecode by Ignition, which is v8's bytecode generator AND also the bytecode interpreter. Next comes the step where the code is actually executed and here's where i have trouble understanding what's going on. I've found out that the same Ignition "executes the bytecodes" and at the same time an Optimizing Compiler, Turbofan in this case, improves the speed of execution by better handling repeating code and then returning the optimized code as Machine Code back.
I thought that executing the bytecodes means converting them to machine code which the CPU will then run, but that's not the case. Since Turbofan is only an optimizing compiler, I've wondered what is it that converts the bytecodes to machine code? I've then found that V8 doesn't compile all functions to machine code, only those that run hot enough for optimized compilation to (likely) be worth the time investment
So, what does it mean for bytecode to be "executed"? The CPU doesn't understand bytecode and the bytecode is not transformed into machine code either. Can anyone explain in simple terms what's going on?