I have been trying to understand the ECMAScript spec in depth and finally started to study it and I am a little confused on how the shape of execution context might look and be implemented by a JavaScript engine.
According to this link:
An execution context contains whatever implementation specific state is necessary to track the execution progress of its associated code. Each execution context has at least the state components listed in Table 25.
Table 25
Component Purpose code evaluation state state Any state needed to perform, suspend, and resume evaluation of the code associated with this execution context. Function If this execution context is evaluating the code of a function object, then the value of this component is that function object. If the context is evaluating the code of a Script or Module, the value is null. Realm The Realm Record from which associated code accesses ECMAScript resources. ScriptOrModule The Module Record or Script Record from which associated code originates. If there is no originating script or module, as is the case for the original execution context created in InitializeHostDefinedRealm, the value is null.
I understand what a callstack is and what an execution context is conceptually, at each function invocation, an execution context is created and appended to the top of the execution context stack. Can someone please clear it up a bit how the state components in the below table might be implemented by a JavaScript engine. I am particularly confused by what realm is and how a JavaScript engine may implement this.
I have a rough idea how this might look given the following code:
var name = "John";
let input = "Hi";
function greet(msg) {
return `${name} says ${msg}`;
}
console.log(greet(input));
From what I can come up with it seems like in pseudo code it would look a bit like this. If anyone can improve the below example or maybe add realm to it that would be appreciated since seeing a visual model helps to understand how some of these abstract concepts work more clearly.
GlobalExecutionContext = {
LexicalEnvironment: {
EnvironmentRecord: {
DeclarativeEnvironmentRecord: {
input: "Hi",
greet: {
LocalExecutionContext: {
LexicalEnvironment: {
EnvironmentRecord: {
DeclarativeEnvironmentRecord: {
msg: "Hi",
},
ObjectEnvironmentRecord: {
arguments: {
0: msg,
length: 1
}
this: < ref.to window obj. >
},
},
OuterEnv: < ref.to LexicalEnvironment of the GlobalExecutionContext > ,
},
},
},
},
ObjectEnvironmentRecord: {
window: < ref.to Global obj. > ,
this: < ref.to window Obj. > ,
},
OuterEnv: < null > ,
},
},
VariableEnvironment: {
EnvironmentRecord: {
DeclarativeEnvironmentRecord: {
name: "John"
},
},
},
}