Implementation process
Runtime environment
Before executing code, V8 prepares the environment for the code to run, including: stack space, global execution context, global scope, extension functions and objects provided by the host environment, and built-in built-in functions.
V8 implements the standards and garbage collection aspects of the language itself, and the host provides apis
Stack space and heap space
- Stack space
Continuous space in memory, first in, first out
Generally used for function calls
Memory is difficult to allocate a block of storage space, V8 has restrictions on stack size, and function calls that are too deep trigger stack overflows
- Heap space
A tree storage structure for storing objects and discrete data
Global execution context and global scope
After initializing the stack space, initialize the global execution context and global scope.
The global execution context includes:
- The variable environment
- Lexical environment (let, const)
- this
The global execution context is not destroyed
Global scope and global execution context relationships
There may be multiple scopes within the same global execution context
var x=5
{
let y=2,
const z=3
}
Copy the code
When V8 calls a function, it enters the execution context of the function, forming a stack structure
Execution context and scope
The execution context can be understood as a stack frame, and the scope is determined when a function is defined or declared.
Lazy parsing and pre-parsing
When the parser encounters a function declaration, it skips the code inside the function and does not generate the AST and bytecode for it
function foo(a, b) {
var m = 1;
var n = 2;
return a + b + m + n;
}
var a = 1;
var b = 4;
foo(1, 2);
Copy the code
If only lazy resolution is performed, how are closures resolved?
function bar() {
var a = 1;
var b = 2;
return function inner(m, n) {
return a + b + m + n;
};
}
f = bar();
Copy the code
Inner does not know that a and B are referenced if only lazy parsing is performed in bar, so in addition to lazy parsing, there is also a pre-parsing process
There are two main purposes of pre-parsing:
- Check for grammatical errors
- Check whether the function references external variables. If it does, copy the external variables referenced on the stack to the heap. When executing the function, reference the external variables directly from the heap