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